Solved

Breaking a loop at the right time

Posted on 2011-02-22
9
366 Views
Last Modified: 2012-05-11
Hello, I can't get the loop below to break at the right time.
When the file is read, the puts() function is outputting all the contents of the columns.
I only want the contents of one column to be output.  abc.txt is a comma delimited CSV.


char str[1024];
char *pch;
FILE *fp;
int first;
int column = 0;

fp=fopen("abc.txt", "r");

if(fp != NULL)
while(fgets(str, sizeof(str), fp) != NULL)
{
first=1;
while((pch=strtok(first ? str: NULL, ",")) != NULL)

column++;

if(column==3)
{
strcpy(team, pch);
puts(team);
}
  
if(column==5)
column=1;

first=0;
}
}

Open in new window

0
Comment
Question by:--TripWire--
  • 4
  • 4
9 Comments
 
LVL 45

Expert Comment

by:Kdo
ID: 34956727
Hi TripWire,

The first lesson is that you need to indent your source code.  It's so much easier to read and understand if the program visually shows you the logic flow.

That said, check the second while() statement.  It loops over the line incrementing column.  I think that you want at least some of the statements under column++ to execute each time the inner while loop executes, not when you've finished scanning the line.


Good Luck,
Kent
0
 

Author Comment

by:--TripWire--
ID: 34956881
Hi Kent,

I like to indent my code, but I just don't like dealing with the indent tags with my code in this forum, but I'll try harder in future.

I'm not quite sure what you mean.  I put the column++ outside my tokenizing while loop, but still no improvement.
What do you mean when you say...
not when you've finished scanning the line.
?
0
 
LVL 45

Expert Comment

by:Kdo
ID: 34957025
Hi TripWire,

I've copied your code below and added a couple of comments.


Kent

char str[1024];
char *pch;
FILE *fp;
int first;
int column = 0;

fp=fopen("abc.txt", "r");

if(fp != NULL)
  while(fgets(str, sizeof(str), fp) != NULL)
  {
    first=1;
    while((pch=strtok(first ? str: NULL, ",")) != NULL)

    column++;  // this is executed as part of the inner while() loop

    if(column==3)  // this line is not.  
                   // column==3 only if there are exactly 3 columns in the line
    {
      strcpy(team, pch);
      puts(team);
    }
  
    if(column==5)
      column=1;

    first=0;
  }
}

Open in new window

0
Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

 
LVL 12

Assisted Solution

by:trinitrotoluene
trinitrotoluene earned 20 total points
ID: 34958550
Your usage of strtok is wrong

pch=strtok(first ? str: NULL, ",")

strtok will use str on its first iteration and then it requires NULL as its 1st argument.

As per your logic first is always 1 so strtok is always going to get "str" to iterate

http://www.cplusplus.com/reference/clibrary/cstring/strtok/
0
 

Author Comment

by:--TripWire--
ID: 34961547
Kent,
I made a mistake in copying the code over.  There are actually braces coupling the code underneath the inner while loop.

What do you mean when you say...
// column==3 only if there are exactly 3 columns in the line

trinitrotoluene,
Adding those braces would couple around first =0; on line 27.  Therefore, resetting my integer value.
0
 

Author Comment

by:--TripWire--
ID: 34961552
Ignore what I said about column 3 in the previous comment.
0
 
LVL 45

Expert Comment

by:Kdo
ID: 34961615
Hi Trip,

  while(fgets(str, sizeof(str), fp) != NULL)
  {
    first=1;
    while((pch=strtok(first ? str: NULL, ",")) != NULL)
      column++;  // this is executed as part of the inner while() loop

    if(column==3)  // this line is not.  
                   // column==3 only if there are exactly 3 columns in the line
    {
      strcpy(team, pch);
      puts(team);
    }

Note the second while loop.  It will execute the test and increment column (the next line) for every token in the line.  Only when you run out of tokens in the line does the line test for column==3!

Perhaps you mean something like this:

  while(fgets(str, sizeof(str), fp) != NULL)
  {
    first=1;
    while((pch=strtok(first ? str: NULL, ",")) != NULL)
    {
      column++;  
      if(column==3)  
      {
        strcpy(team, pch);
        puts(team);
      }
      if(column==5)
        column=1;

      first=0;
    }
 }
0
 

Author Comment

by:--TripWire--
ID: 34981537
Hey Kent,

Thanks but that's what I have.
But my program is outputting every token.  I just want to observe what's in my 3rd column.
0
 
LVL 45

Accepted Solution

by:
Kdo earned 80 total points
ID: 34981740
Hi Trip,

If you're seeing every token, it's not because of this function.  Is there somewhere else in the program that you might be parsing each line?

Now, there is still an issue or two with that code, but nothing that should cause it to print every token.

The function below is a bit smaller.  It resets column every time a line is read, doesn't worry about wrap, and prints the 3rd token, 1 per line.  All slightly different than the other functions.


Give it a try,
Kent

while(fgets(str, sizeof(str), fp) != NULL)
  {
    pch = strtok (str, ",");
    column == 0;
    while(pch)
    {
      if((++column) == 3)  
      {
        printf ("%s\n", pch);
        break;
      }
      pch = strtok (NULL, ",");
    }
 }

Open in new window

0

Featured Post

Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Visual studio sees sql server but cannot connect 7 62
please insert disk adobe master collection6 9 868
Unresolved External Symbols 3 81
White board coding practice 3 86
Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to create, access, and change arrays in the C programming language.

785 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question