Solved

Breaking a loop at the right time

Posted on 2011-02-22
9
389 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 45

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 45

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
Independent Software Vendors: 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 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: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 45

Accepted Solution

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

On Demand Webinar: Networking for the Cloud Era

Ready to improve network connectivity? Watch this webinar to learn how SD-WANs and a one-click instant connect tool can boost provisions, deployment, and management of your cloud connection.

Question has a verified solution.

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

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
Examines three attack vectors, specifically, the different types of malware used in malicious attacks, web application attacks, and finally, network based attacks.  Concludes by examining the means of securing and protecting critical systems and inf…
The goal of this video is to provide viewers with basic examples to understand how to use strings and some functions related to them in the C programming language.
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

707 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