?
Solved

Breaking a loop at the right time

Posted on 2011-02-22
9
Medium Priority
?
392 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--
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 4
9 Comments
 
LVL 46

Expert Comment

by:Kent Olsen
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 46

Expert Comment

by:Kent Olsen
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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 12

Assisted Solution

by:trinitrotoluene
trinitrotoluene earned 80 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 46

Expert Comment

by:Kent Olsen
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 46

Accepted Solution

by:
Kent Olsen earned 320 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

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

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

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…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The goal of this video is to provide viewers with basic examples to understand recursion in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use for-loops in the C programming language.

800 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