Solved

Breaking a loop at the right time

Posted on 2011-02-22
9
350 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
 
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
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The goal of this video is to provide viewers with basic examples to understand recursion in the C programming language.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

757 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

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now