LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
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-06-2014, 02:09 PM   #1
PeterUK
Member
 
Registered: May 2009
Posts: 281

Rep: Reputation: 16
Wrong value returning from a function on C


Hi Guys!

I am having problem understanding why its returning wrong value from a function.

Not to waste lot of time in getting a short code version to post here I will explain what I am doing de simple way.

I am opening a txt file which it only contain number of 3 digits (characters) so I want a function which search on the file section and then return the number in integer variable.

so what I have done, after opening the file,
Quote:
while(fgets(buffer, 200, file) != NULL)
{
token = strtok(buffer, ","); // noticed its a cvs file but I am simplifying here
int n;
n = get_number2 (token);
Now in the function:
I pass that char* str to the function and do my statements
and print the number as:

Quote:
printf ("%i\n",number_final);
And it print fine within the function now I return the integer value by:

Quote:
return number;
now I print in main as
Quote:
printf ("This is number = %i\n",n);
Now the real question if I type in the txt file like 376 it return 376 with no problem, buy if I type 100 it (print/return) 1, so it does with 300 for example it print 3, why does the it cut the zeros on the right? How can I fix it? Thanks
 
Old 03-06-2014, 02:34 PM   #2
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Quote:
Originally Posted by PeterUK View Post
Not to waste lot of time in getting a short code version to post here I will explain what I am doing de simple way.
So far as I can tell you are wasting our time trying to avoid "waste" of a little of your time.

Since you did not even show the source code of the function that returned the wrong value, how are we supposed to guess your bug.

You implied you expect number_final and number to be the same thing within your function. But you gave no reason for us to trust that.

Last edited by johnsfine; 03-06-2014 at 02:37 PM.
 
1 members found this post helpful.
Old 03-07-2014, 08:23 AM   #3
PeterUK
Member
 
Registered: May 2009
Posts: 281

Original Poster
Rep: Reputation: 16
As a lot of people have seen the post but none one has reply I decided to make a code for here, here we go:

I have cleaned as short as possible, also noticed if you think I am doing something the hard way as there is some function in a library to do it easier please let me know

To run this you need to create a text file called "Q.txt" and just compile the code should do.

The code:
Quote:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>



int get_number2( char* str)
{
char
* cpy,
* pos;
int temp_track = 0;

int number1=0;
int number2=0;
int number21=0;
int number_final=0;

//-------------- int more_than_one_number=0;
int number_to=0;
for( pos = cpy = str; *pos; ++pos ){
if((temp_track == 0) && (( *pos > 47) && (*pos < 58))){
puts("We have got a number 1");
printf ("%i\n",*pos-48);
number1= (*pos-48);
printf ("%i\n",number1);
temp_track++;}

else if ((temp_track == 1) && ( *pos == 32)){
puts("We have ONLY one number we are getting out");
break;
}


else if((temp_track == 1) && (( *pos > 47) && (*pos < 58))){
puts("We have got a number 2");
printf ("%i\n",*pos-48);
number2= (*pos-48);
printf ("%i\n",number2);
number_final = (number1*10) + number2;
printf ("%i\n",number_final);
temp_track++;}

else if((temp_track == 2) && (( *pos > 47) && (*pos < 58))){
puts("We have got a number 3");
printf ("%i\n",*pos);
number21= (*pos-48);
printf ("%i\n",number21);
number_final = (number_final*10) + number21;
printf ("%i\n",number_final);

temp_track++;}

}

if ((number1 > 0) && (number2 == 0) && (number21 == 0)) {number_to = number1;}
else if ((number1 > 0) && (number2 > 0) && (number21 == 0)) {number_to = number_final;}
else if ((number1 > 0) && (number2 > 0) && (number21 > 0)) {number_to = number_final;}



//return str;
return number_to;
}



int main()
{

char* filename = "Q.txt";
FILE *file;


//------Open the file--------------------------------
if((file = fopen(filename, "r")) == NULL)
{
puts("Failed to open the file.txt");
exit (1);
}
else puts("File file.txt opened");

char buffer[200];
char *token;
while(fgets(buffer, 200, file) != NULL)
{
token = strtok(buffer, ",");
puts(token);
int n;
n = get_number2 (token);
printf ("The number is = %i\n",n);
puts(token);
}

//Closing the file:
if (fclose(file) != 0) {puts("Failed to close file2"); exit (1); }

return 0;
}
So if you type in 300 in text file in 92 I get a error, there is something wrong in print function or how I am returning from the function?

If I type 389 in the text file I get, 389 as it should, why does it cut the 0? Thanks

Last edited by PeterUK; 03-07-2014 at 11:32 AM.
 
Old 03-07-2014, 09:01 AM   #4
turtleli
Member
 
Registered: Aug 2012
Location: UK
Posts: 206

Rep: Reputation: Disabled
You should use CODE tags and not QUOTE tags to make the code easier to read.

I would suggest you use the strtol family of functions in stdlib.h to perform string to integer conversions.
 
Old 03-07-2014, 09:38 AM   #5
PeterUK
Member
 
Registered: May 2009
Posts: 281

Original Poster
Rep: Reputation: 16
Quote:
Originally Posted by turtleli View Post
You should use CODE tags and not QUOTE tags to make the code easier to read.

I would suggest you use the strtol family of functions in stdlib.h to perform string to integer conversions.
I need to explore more "strtol" as the text file will also have characters.

But I have tried with atoi and it kind of work but this function convert the whole number and not the character.

I did create another int variable and did

Code:
number199 = atoi(pos);
printf ("%i\n",number199);
And in the first look it take the hole number, if I do it in the second loop as it has move it will take 80, so it take until reach something its not a number. Right?

Now I got something may work, but I still dont know why it work fine (no even warning) within the function but when it return to main is cut the 0 values? Anyone?

Last edited by PeterUK; 03-07-2014 at 09:53 AM.
 
Old 03-07-2014, 10:32 AM   #6
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,860
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
Code:
if ((number1 > 0) && (number2 == 0) && (number21 == 0)) {number_to = number1;}
Do you remember writing this line?

Note: You should do something like this:

Code:
int numval (const char *p, int *to)
{
    int err;
    int n= 0;
    const char *q= p;

    while (isdigit ((unsigned char)*q)) {
        n= n*10 + (*q-'0');
        ++q;
    }
    if (q==p || *q!='\0') err= EOF;
    else                  err= 0;
    *to= n;
    return err;
}

Last edited by NevemTeve; 03-07-2014 at 10:44 AM.
 
Old 03-07-2014, 10:33 AM   #7
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Quote:
Originally Posted by PeterUK View Post
none one has reply
I'm wondering how insulted to be from that comment.

Quote:
you think I am doing something the hard way
That is an extreme understatement.

Even if you don't know a library function to do the whole job, you should try to think about the steps more generally. You coded a loop but then used if statements to defeat the purpose of your loop and do all the work individually.

Quote:
why does it cut the 0?
Because you put in extra code to do exactly that.

I have no guess what you thought you were doing with the code that goes out of its way to ignore the 00 in digit followed by 00, but it wasn't a simple accident (side effect of wrong code with some other purpose). Your code specifically ignore the 00 when one digit is followed by 00.
 
Old 03-07-2014, 10:36 AM   #8
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
Isn't this the kind of thing that scanf() and family was intended for?
 
Old 03-07-2014, 11:04 AM   #9
PeterUK
Member
 
Registered: May 2009
Posts: 281

Original Poster
Rep: Reputation: 16
Quote:
Originally Posted by johnsfine View Post
I'm wondering how insulted to be from that comment.
Please dont be, that was not the intention.


Quote:
Even if you don't know a library function to do the whole job, you should try to think about the steps more generally. You coded a loop but then used if statements to defeat the purpose of your loop and do all the work individually.
I understands you point, I felt I was using to many variable, :-). Never the less I do still use the loop to increment along "token".


Quote:
Because you put in extra code to do exactly that.
Could you please explain a bit more.

Code:
I have no guess what you thought you were doing with the code that goes out of its way to ignore the 00 in digit followed by 00, but it wasn't a simple accident (side effect of wrong code with some other purpose).  Your code specifically ignore the 00 when one digit is followed by 00.
Could you please explain me more? I still don't see it (if its silly pls point me what topic should I read). when I print the number before returning is all with 00 and printing after returning is without.

Also I would like to add that this function I want it to do more like recognize paten, number like 12B, group of numbers 10-67 (in character from the txt file), I suppose I could also record the position of "*pos" and them figure out what was on the text file, Right?

Last edited by PeterUK; 03-07-2014 at 11:07 AM.
 
Old 03-07-2014, 11:29 AM   #10
schneidz
LQ Guru
 
Registered: May 2005
Location: boston, usa
Distribution: fedora-35
Posts: 5,313

Rep: Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918
i think this should help:
Code:
[schneidz@hyper ~]$ cat peter.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>



int main()
{

char* filename = "Q.txt"; // could be "Streets_Postcode_rwa_test_small" but the file must be call like that (no extention)
FILE *file;


//------Open the file--------------------------------
if((file = fopen(filename, "r")) == NULL)
{
puts("Failed to open the file.txt");
exit (1);
}
else puts("File file.txt opened");

char buffer[200];
char *token;
while(fgets(buffer, 200, file) != NULL)
{
token = strtok(buffer, ",");
puts(token);
int n;
n = atoi(token);
printf ("The number is = %i\n",n);
puts(token);
}

//Closing the file:
if (fclose(file) != 0) {puts("Failed to close file2"); exit (1); }

return 0;
} 
[schneidz@hyper ~]$ cat Q.txt 
300
[schneidz@hyper ~]$ ./peter.x 
File file.txt opened
300

The number is = 300
300
 
Old 03-07-2014, 12:48 PM   #11
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Quote:
Originally Posted by PeterUK View Post
Could you please explain a bit more.
Look at post #6 of this thread.
I type slowly, so I didn't see it before writing post #7.
But in the top of post #6, NevemTeve tells you more specifically the line of code.

Edit: Later I did realize the INTENT of the line of code that is causing the problem. It does not ONLY cause that problem. It also covers up a flaw in the earlier code for a different case.

All of this comes back to thinking more generally, which is also key to ever really learning to program. You should not focus on one step at a time or one case at a time. You need to understand what is in common across all cases of multiple steps, and code more generally and more simply. Use more thought and a lot less code.

Last edited by johnsfine; 03-07-2014 at 02:23 PM.
 
Old 03-07-2014, 01:52 PM   #12
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,860
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
Also these messages could be improved:
Code:
file= fopen (filename, "r");
if (file==NULL) {
    fprintf (stderr, "*** Failed to open file '%s': %s\n", filename, strerror (errno));
    exit (1);
} else {
    fprintf (stderr, "File '%s' opened\n", filename);
}
 
Old 03-11-2014, 07:39 AM   #13
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,882
Blog Entries: 13

Rep: Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930
OP, what exactly are you trying to do here? In simple descriptive form please, not tons of code clips.

Are you trying to parse a string of data which could be unknown in content, but bound by a certain set of general syntactical rules?

Is your get_number2() function just a special form of scanf()?

What's the expected format (syntax) of a line from your text file?

It would also help to know if the reason for this exercise is pure experimentation, or to solve a problem which you don't feel can be directly resolved via a library function.
 
Old 03-11-2014, 12:16 PM   #14
PeterUK
Member
 
Registered: May 2009
Posts: 281

Original Poster
Rep: Reputation: 16
Quote:
Originally Posted by NevemTeve View Post
Also these messages could be improved:
Code:
file= fopen (filename, "r");
if (file==NULL) {
    fprintf (stderr, "*** Failed to open file '%s': %s\n", filename, strerror (errno));
    exit (1);
} else {
    fprintf (stderr, "File '%s' opened\n", filename);
}
Thanks for this, it print the file name by a variable and errno will give more info when it crash, tested and updated, thanks
 
Old 03-11-2014, 01:10 PM   #15
PeterUK
Member
 
Registered: May 2009
Posts: 281

Original Poster
Rep: Reputation: 16
Quote:
Originally Posted by rtmistler View Post
OP, what exactly are you trying to do here? In simple descriptive form please, not tons of code clips.
I was stuck on the problem why it print the right number within the function and when it returns it cuts the zeros, I still don't know why as if its ASCII values should them just be return intact?
Quote:
Are you trying to parse a string of data which could be unknown in content, but bound by a certain set of general syntactical rules?
YES
Quote:
Is your get_number2() function just a special form of scanf()?
I supposed I need to review further scanf perhaps I can do it with it and I am doing it the long way :-/



Quote:
What's the expected format (syntax) of a line from your text file?
The algorithm will be something like this.(the text is csv file)

-if at first is number - it bellow to group A and get number into variable, get 4 more following fields saved into variables.
-if at first is f or F - below - to group B get the number which fallow by space and storage into variable, then get following 3 files and save/storage into variables.
-if its none the above- its in group C so storage into a variable first field, but the second field could be: number follow it by string to be storage independently or it would be a range of number like 76-86 and then storage individually the 10 variations plus record the to remaining fields.

When I said record/storage string or filed it will be an array as its a string of characters of difference lengths

I was planning to do logic on an evaluation of ASCII character by positioning and I would create a structure for storage but its not needed I was thinking in dropping it into a database (after all properly storage) and a text file after some formatting.
Quote:
It would also help to know if the reason for this exercise is pure experimentation, or to solve a problem which you don't feel can be directly resolved via a library function.
I guess I am doing it like this by inexperience/ignorance of the language/libraries. I think of myself as learner level, it's for a part of something I am developing but its part of my review/learning goals, so very flexible.
 
  


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
returning boolean from function ? cmosentine Programming 3 02-16-2012 10:27 AM
time() function not returning jiml8 Programming 5 04-09-2008 01:03 PM
returning different types of variables from a function knobby67 Programming 3 02-08-2008 08:53 PM
Perl - returning array from a function rose_bud4201 Programming 6 07-13-2007 01:02 AM
returning an array from a function.. javascript sonesay Programming 1 06-07-2004 05:28 AM

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

All times are GMT -5. The time now is 07:48 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