Thread: Atoi problem

  1. #1
    Registered User
    Join Date
    Dec 2006
    Posts
    51

    Atoi problem

    Okay so I now I have NO idea why my code is messing up. I have a buffer which loads data from a file. And now I put a section of that buffer into this character array and it shows up fine on my computer aka
    buffer: 12345
    A[10]:12345
    But then when I try to convert A it keeps showing up as 0 and I have no idea as to why it keeps showing up as 0. Heres the for loop I'm using.

    Code:
    char buff[880];
    char A[10];
    		for(z=x; z<start+33; z++){
    			A[z]=buff[z];
    			cout<<A[z]<<' '<<buff[z]<<endl;
    			if(z==5+x1){
    				cout<<"blah!\n"<<atoi(A)<<endl;
    				Accounts->Acc_Number=atoi(A);
    				cout<<Accounts->Acc_Number;
    			}
    			x++;	
    		}

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    I would recommend using strtol() instead of atoi(). atoi is good for well-formed single numbers, but can easily be confused into doing "the wrong thing" when fed anything other than plain number strings. "12345" is fine, but " 12345" or "12345A" may not be.

    strtol takes three parameters:
    Code:
    long strtol(const char *  nptr, char ** endptr, int base);
    http://www.hmug.org/man/3/strtol.php

    The first is a pointer to your string, the second gives you a pointer to where in the string the number "ended" (or NULL if all of the string was "consumed"), and base is either 0 (let strtol figure out), 10 or say 16 if you have hexadecimal numbers.

    If nothing else, this will help you find out where each number "starts to go wrong", as you can use the endptr to show you what didn't translate into a number.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    If you're using C++, use a stringstream or boost lexical_cast.

    Does your code ensure that the string ends in a null character? Since you're using C style strings, if you forget to terminate the string with a null then atoi, strtol, stringstreams and lexical_cast might all fail.

  4. #4
    Registered User
    Join Date
    Dec 2006
    Posts
    51
    How would I use the endptr to figure out where it went wrong? Also Daved I made sure to add the /0 but that didn't help.

    Heres my full function including my structure I am using.

    Code:
    struct Acc_var{
    	float Acc_Balance;
    	long int Acc_Number;
    	char Name[25];
    };
    
    int LoadDataFromFile(Acc_var *Accounts){
    	int x=0,start=0,z=0;
    	int x1;
    	int count=0;
    	char buff[880];//Only needs 880 for the buffer
    	char A[10];
    	ifstream Atmfile;
    
    	Atmfile.open ("Atm.txt");
    	if (Atmfile.fail()) {
    		cout<<"Couldn't open Atm.txt\n";
    		return -1;
    	}
    	else{
    	   while (!Atmfile.eof() )
    		{
    		   buff[x]=Atmfile.get();//Grabs anything in the file including whitespaces
    		   if(buff[x]=='\n'){//Gets ride of the new lines
    				buff[x]=Atmfile.get();
    		   }
    		   cout<<x<<' '<<buff[x]<<endl;//Shows what is inputed into the buffer and what space in the buffer
    		   x++;
    		 }
    	}
    
    cout<<endl<<endl<<endl;
    x=0;
    	for(count=0; count<3; count++){//as a test run only runs 3 times
    
    		for(int N=start; N<start+24; N++){//Start is where the loop ended last
    			Accounts->Name[N]=buff[N];//Puts the charaters from the buffer into Name
    			x++;
    		}
    
    		x+=3;//moves through 3 whitespaces
    		cout<<x<<endl;//Says its 27
    		x1=x;
    
    		for(z=x; z<start+33; z++){//Loops 5 times
    			A[z]=buff[z];//Grabs the 5 numbers from the buffer file and puts them into A[10];
    			cout<<A[z]<<' '<<buff[z]<<endl;//Couts that they are fine
    			if(z==5+x1){//At the 5th loop it SHOULD convert the array in A[10] to an int but it is display 0's for some reason.
    				cout<<"A:"<<atoi(A)<<endl;
    				Accounts->Acc_Number=atoi(A);
    				cout<<Accounts->Acc_Number;
    			}
    			x++;	
    		}
    		x+=3;
    		cout<<x<<endl;
    		for(int r=z; r<start+44; r++){
    			Accounts->Acc_Balance=buff[x];
    			x++;
    		}
    		start=x;
    		Accounts++;
    	}
    
    
    
    	Atmfile.close();
    return 0;
    }
    This is my text file
    Code:
    Iwan Bodnarchuk             12345   000000100
    Bobby McGavier              54321   100000000
    And this is what my output is:

    x:27
    A[z]=1 buff[z]=1
    A[z]=2 buff[z]=2
    A[z]=3 buff[z]=3
    A[z]=4 buff[z]=4
    A[z]=5 buff[z]=5

    A(Atoi)=0
    Last edited by Shadowwoelf; 09-21-2007 at 07:36 PM.

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > while (!Atmfile.eof() )
    Read the FAQ on why this is bad.

    Also, you
    - don't check for overflow of your buffer
    - append a \0 when you're done
    This is a common problem for all your string manipulation.


    > Accounts->Name[N]=buff[N];
    So on anything other than the first iteration, when N is marching through buff, you're writing WAY WAY WAY beyond the end of Name.

    Ditto for building your temporary z array.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User
    Join Date
    Dec 2006
    Posts
    51
    I know the maximum buffer size(Unless my teacher decides to purposefully crash the program)which is 900. Adding the '\0' didn't seem to help at all. Also I know that it might not work the second or third time around because I am just trying to get it to work the first loop.

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Well you need to use TWO subscripts
    - one indexes the array you're copying from
    - the other indexes the array you're copying to.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  8. #8
    Registered User
    Join Date
    Dec 2006
    Posts
    51
    Figured it out. Salem your entire post about Buffer overflow reminded me to look at where the temporary buffer is storing its data which of course was outside of its domain.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Someone having same problem with Code Block?
    By ofayto in forum C++ Programming
    Replies: 1
    Last Post: 07-12-2007, 08:38 AM
  2. A question related to strcmp
    By meili100 in forum C++ Programming
    Replies: 6
    Last Post: 07-07-2007, 02:51 PM
  3. WS_POPUP, continuation of old problem
    By blurrymadness in forum Windows Programming
    Replies: 1
    Last Post: 04-20-2007, 06:54 PM
  4. Problem with atoi()?
    By ruthgrin in forum C++ Programming
    Replies: 4
    Last Post: 03-19-2006, 12:25 PM
  5. Laptop Problem
    By Boomba in forum Tech Board
    Replies: 1
    Last Post: 03-07-2006, 06:24 PM