LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 03-30-2023, 03:35 PM   #1
jmgibson1981
Senior Member
 
Registered: Jun 2015
Location: Tucson, AZ USA
Distribution: Debian
Posts: 1,151

Rep: Reputation: 393Reputation: 393Reputation: 393Reputation: 393
C - Function only returns value if an irrelevant printf is in the function.


Code:
char * file_search_func(FILE * file, const char * searchstr,
                      const char * delimiter, const int field)
{
  // declare and initialize
  char * token = NULL;
  char * retval = NULL;
  char buffer[256];
  int counter = 0;
  int keepgoing = 0;

  // loop until find identifier in string. typically first field
  // tokenize once found
  while (keepgoing == 0) {
    if (fgets(buffer, 256, file)) {
//      printf("indeed\n");
      if (strstr(buffer, searchstr)) {
        // tokenize and begin processing
        token = strtok(buffer, delimiter);
        while (token) {
          // if proper value copy to pointer
          if (counter == field) {
            retval = token;
            keepgoing = 1;
            break;
          } else {
          // else continue to next token until found
            counter++;
            token = strtok(NULL, delimiter);
          }
        }
      }
    }
  }

  // reset file to beginning
  rewind(file);
  return(retval);
}
I am so lost right now. I get my expected return value but only if the printf("indeed\n"); is uncommented. If it's commented nothing comes up on the terminal... I have a feeling its going to be staring me in the face but I simply cannot comprehend how a printf statement changes how everything else works :/
 
Old 03-30-2023, 03:38 PM   #2
dugan
LQ Guru
 
Registered: Nov 2003
Location: Canada
Distribution: distro hopper
Posts: 11,249

Rep: Reputation: 5323Reputation: 5323Reputation: 5323Reputation: 5323Reputation: 5323Reputation: 5323Reputation: 5323Reputation: 5323Reputation: 5323Reputation: 5323Reputation: 5323
The newline in the printf flushes the standard output buffer. Maybe that has something to do with it?
 
Old 03-30-2023, 04:58 PM   #3
dugan
LQ Guru
 
Registered: Nov 2003
Location: Canada
Distribution: distro hopper
Posts: 11,249

Rep: Reputation: 5323Reputation: 5323Reputation: 5323Reputation: 5323Reputation: 5323Reputation: 5323Reputation: 5323Reputation: 5323Reputation: 5323Reputation: 5323Reputation: 5323
Honestly, your returning of a char pointer just smells unsafe to me. My concern is: does the memory address pointed to by the pointer still contain the same thing after the function returns? It looks like the answer is "not necessarily", because it points to a stack-allocated buffer that gets destroyed at the return statement. I changed it to allocate a string for the return value and then return that, and that works without the stray printf.

Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char *file_search_func(FILE *file, const char *searchstr,
                       const char *delimiter, const int field)
{
    // declare and initialize
    char *token = NULL;
    char *retval = NULL;
    char buffer[256];
    int counter = 0;
    int keepgoing = 0;

    // loop until find identifier in string. typically first field
    // tokenize once found
    while (keepgoing == 0)
    {
        if (fgets(buffer, 256, file))
        {
            if (strstr(buffer, searchstr))
            {
                // tokenize and begin processing
                token = strtok(buffer, delimiter);
                while (token)
                {
                    // if proper value copy to pointer
                    if (counter == field)
                    {
                        retval = token;
                        keepgoing = 1;
                        break;
                    }
                    else
                    {
                        // else continue to next token until found
                        counter++;
                        token = strtok(NULL, delimiter);
                    }
                }
            }
        }
    }

    // reset file to beginning
    rewind(file);

    char *s = (char *)malloc(strlen(retval) * sizeof(char) + 1);
    strcpy(s, retval);
    return s;
}

int main()
{
    // a.txt contains one line:
    // b;
    FILE *f = fopen("a.txt", "r");
    char *s = file_search_func(f, "b", ";", 0);
    printf("%s\n", s);
    free(s);
    fclose(f);
}

Last edited by dugan; 03-30-2023 at 05:11 PM.
 
3 members found this post helpful.
Old 03-30-2023, 06:48 PM   #4
jmgibson1981
Senior Member
 
Registered: Jun 2015
Location: Tucson, AZ USA
Distribution: Debian
Posts: 1,151

Original Poster
Rep: Reputation: 393Reputation: 393Reputation: 393Reputation: 393
Thank you much. I was afraid of that. I had it working a similar way and was trying to eliminate having to call free outside the function. At least it now doesn't rely on a pass by reference.
 
Old 04-01-2023, 11:07 AM   #5
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,786

Rep: Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083
Additional minor suggestion: You can use while (retval == NULL) instead of while (keepgoing == 0), and then the keepgoing variable is redundant.

By the way, since 0 is usually considered false, your use of while (keepgoing == 0) looks very confusing to me (i.e., it reads like "if not keepgoing then do keep going, today is opposite day!").
 
1 members found this post helpful.
Old 04-01-2023, 11:45 AM   #6
jmgibson1981
Senior Member
 
Registered: Jun 2015
Location: Tucson, AZ USA
Distribution: Debian
Posts: 1,151

Original Poster
Rep: Reputation: 393Reputation: 393Reputation: 393Reputation: 393
I always thought it was the other way around. I'll make those changes. Was thinking of a typical shell command return 0 if success.
 
1 members found this post helpful.
Old 04-01-2023, 11:56 AM   #7
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,880
Blog Entries: 1

Rep: Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871
That's right, shell uses another logic: 0=success, nonzero=errorcode
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] D&D motion event handler called only once. [gtkmm 3 && goocanvasmm (irrelevant)] Amonith Programming 1 01-06-2012 09:54 AM
strange value assignments variable = value, value?? ostrow30 Programming 2 07-24-2011 07:59 AM
difference between value *value and value * value PoleStar Linux - Newbie 1 11-26-2010 03:37 PM
[SOLVED] printf $"Hello $var\n" vs. printf "Hello $var\n" -- not a typo. What is it? GrapefruiTgirl Programming 2 10-21-2010 08:21 AM
How is 'man 3 printf' different from 'man printf' ?? purpleburple Linux - General 3 09-23-2002 12:29 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 07:03 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration