Fread binary file dynamic size string - c

I've been working on this assignment, where I need to read in "records" and write them to a file, and then have the ability to read/find them later. On each run of the program, the user can decide to write a new record, or read an old record (either by Name or #)
The file is binary, here is its definition:
typedef struct{
char * name;
char * address;
short addressLength, nameLength;
int phoneNumber;
}employeeRecord;
employeeRecord record;
The way the program works, it will store the structure, then the name, then the address. Name and address are dynamically allocated, which is why it is necessary to read the structure first to find the size of the name and address, allocate memory for them, then read them into that memory.
For debugging purposes I have two programs at the moment. I have my file writing program, and file reading.
My actual problem is this, when I read a file I have written, i read in the structure, print out the phone # to make sure it works (which works fine), and then fread the name (now being able to use record.nameLength which reports the proper value too).
Fread however, does not return a usable name, it returns blank.
I see two problems, either I haven't written the name to the file correctly, or I haven't read it in correctly.
Here is how i write to the file: where fp is the file pointer. record.name is a proper value, so is record.nameLength. Also i am writing the name including the null terminator. (e.g. 'Jack\0')
fwrite(&record,sizeof record,1,fp);
fwrite(record.name,sizeof(char),record.nameLength,fp);
fwrite(record.address,sizeof(char),record.addressLength,fp);
And i then close the file.
here is how i read the file:
fp = fopen("employeeRecord","r");
fread(&record,sizeof record,1,fp);
printf("Number: %d\n",record.phoneNumber);
char *nameString = malloc(sizeof(char)*record.nameLength);
printf("\nName Length: %d",record.nameLength);
fread(nameString,sizeof(char),record.nameLength,fp);
printf("\nName: %s",nameString);
Notice there is some debug stuff in there (name length and number, both of which are correct). So i know the file opened properly, and I can use the name length fine. Why then is my output blank, or a newline, or something like that? (The output is just Name: with nothing after it, and program finishes just fine)
Thanks for the help.

I tried your code and it worked fine. In order, here is the output, a hexdump of the file, and your source made to compile.
Update: Updated code to read name and address from stdin or command-line arguments.
prompt$ g++ -g -Wall -o test_records test_records.cpp
prompt$ echo -e "Test User\nSomeplace, Somewhere" | ./test_records
sizeof(employeeRecord) = 24
Number: 5551212
Name Length: 9
Name: Test User
prompt$ hexdump -C employeeRecord
00000000 90 f7 bf 5f ff 7f 00 00 70 f7 bf 5f ff 7f 00 00 |..._....p.._....|
00000010 14 00 09 00 6c b4 54 00 54 65 73 74 20 55 73 65 |....l.T.Test Use|
00000020 72 53 6f 6d 65 70 6c 61 63 65 2c 20 53 6f 6d 65 |rSomeplace, Some|
00000030 77 68 65 72 65 |where|
00000035
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct{
char * name;
char * address;
short addressLength, nameLength;
int phoneNumber;
}employeeRecord;
int main(int argc, char *argv[])
{
employeeRecord record;
#if 0
// Commmand line arguments
if (argc < 3)
return 1;
record.nameLength = strlen(argv[1]);
record.name = (char *)malloc(sizeof(char)*(record.nameLength + 1));
strncpy(record.name, argv[1], record.nameLength + 1);
record.addressLength = strlen(argv[2]);
record.address = (char *)malloc(sizeof(char)*(record.addressLength + 1));
strncpy(record.address, argv[2], record.addressLength + 1);
#else
// stdin
char input[1024];
fgets(input, sizeof(input), stdin);
record.nameLength = strlen(input);
record.name = (char *)malloc(sizeof(char)*(record.nameLength + 1));
strncpy(record.name, input, record.nameLength + 1);
fgets(input, sizeof(input), stdin);
record.addressLength = strlen(input);
record.address = (char *)malloc(sizeof(char)*(record.addressLength + 1));
strncpy(record.address, input, record.addressLength + 1);
#endif
record.phoneNumber = 5551212;
FILE *fp = NULL;
printf("sizeof(employeeRecord) = %lu\n", sizeof(employeeRecord));
// Write
fp = fopen("employeeRecord","w");
fwrite(&record,sizeof(employeeRecord),1,fp);
// Note: we're not including terminating NULLs.
fwrite(record.name,sizeof(char),record.nameLength,fp);
fwrite(record.address,sizeof(char),record.addressLength,fp);
fclose(fp);
// Read
fp = fopen("employeeRecord","r");
fread(&record,sizeof(employeeRecord),1,fp);
printf("Number: %d\n",record.phoneNumber);
char *nameString = (char *)malloc(sizeof(char)*(record.nameLength + 1));
printf("\nName Length: %d",record.nameLength);
fread(nameString,sizeof(char),record.nameLength,fp);
nameString[record.nameLength] = '\0';
printf("\nName: %s",nameString);
printf("\n");
fclose(fp);
return 0;
}

I would like to add my input....since you are dumping the memory structure to disk, the pointer addresses used to hold the data would most certainly be valid prior to dumping, but when reading from them, the pointer addresses could be invalid....which would explain why the character pointer is not showing the name...

Firstly, a nitpick: you never need sizeof (char) - it's 1, always, by definition.
As for the blank name output: do you perhaps need a newline after the %s to flush the output? I've seen weird behaviour when you leave this out, and you don't state which platform you are using. If the platform's printf() is implemented bizarrely enough, you could have the format string printed and flushed, but the name itself stuck in the C library's buffers when your program exits.
And I'm never happy about reading or writing blobs of binary data like a struct to and from files. Realise that by doing so you're promising your program that it will only ever read what it wrote on the same platform. You couldn't write a file on, say, a 64-bit host and read the file back in on a 16-bit microwave oven controller.

Related

How to send image or binary data through HTTP POST request in C

I'm trying to POST a binary file to a web server with a client program written in C (Windows). I'm pretty new to socket programming, so tried POST requests using multipart/form-data with plain text messages, and text-based files (.txt, .html, .xml). Those seem to work fine. But when trying to send a PNG file, I'm running into some problems.
The following is how I read the binary file
FILE *file;
char *fileName = "download.png";
long int fileLength;
//Open file, get its size
file = fopen(fileName, "rb");
fseek(file, 0, SEEK_END);
fileLength = ftell(file);
rewind(file);
//Allocate buffer and read the file
void *fileData = malloc(fileLength);
memset(fileData, 0, fileLength);
int n = fread(fileData, 1, fileLength, file);
fclose(file);
I confirmed that all the bytes are getting read properly.
This is how I form my message header and body
//Prepare message body and header
message_body = malloc((int)1000);
sprintf(message_body, "--myboundary\r\n"
"Content-Type: application/octet-stream\r\n"
"Content-Disposition: form-data; name=\"myFile\"; filename=\"%s\"\r\n\r\n"
"%s\r\n--myboundary--", fileName, fileData);
printf("\nSize of message_body is %d and message_body is \n%s\n", strlen(message_body), message_body);
message_header = malloc((int)1024);
sprintf(message_header, "POST %s HTTP/1.1\r\n"
"Host: %s\r\n"
"Content-Type: multipart/form-data; boundary=myboundary\r\n"
"Content-Length: %d\r\n\r\n", path, host, strlen(message_body));
printf("Size of message_header is %d and message_header is \n%s\n", strlen(message_header), message_header);
The connection and sending part also works fine as the request is received properly. But, the received png file is ill-formatted.
The terminal prints out the following for fileData if I use %s in printf
ëPNG
I searched around and came to know that binary data doesn't behave like strings and thus printf/ sprintf/ strcat etc. cannot be used on them. As binary files have embedded null characters, %s won't print properly. It looks like that is the reason fileData only printed the PNG header.
Currently, I send two send() requests to server. One with the header and the other with body and footer combined. That was working for text-based files. To avoid using sprintf for binary data, I tried sending one request for header, one for binary data (body) & one for footer. That doesn't seem to work either.
Also, found that memcpy could be used to append binary data to normal string. That didn't work either. Here is how I tried that (Not sure whether my implementation is correct or not).
sprintf(message_body, "--myboundary\r\n"
"Content-Disposition: form-data; name=\"text1\"\r\n\r\n"
"text default\r\n"
"--myboundary\r\n"
"Content-Type: application/octet-stream\r\n"
"Content-Disposition: form-data; name=\"myFile\"; filename=\"%s\"\r\n\r\n", fileName);
char *message_footer = "\r\n--myboundary--";
char *message = (char *)malloc(strlen(message_body) + strlen(message_footer) + fileLength);
strcat(message, message_body);
memcpy(message, fileData, fileLength);
memcpy(message, message_footer, strlen(message_footer));
I'm stuck at how I could send my payload which requires appending of string (headers), binary data (payload), string (footer).
Any advice/ pointers/ reference links for sending the whole file would be appreciated. Thank You!
How to print binary data
In your question, you stated you were having trouble printing binary data with printf, due to the binary data containing bytes with the value 0. Another problem (that you did not mention) is that binary data may contain non-printable characters.
Binary data is commonly represented in one of the following ways:
in hexadecimal representation
in textual representation, replacing non-printable characters with placeholder characters
both of the above
I suggest that you create your own simple function for printing binary data, which implements option #3. You can use the function isprint to determine whether a character is printable, and if it isn't, you can place some placeholer character (such as 'X') instead.
Here is a small program which does that:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
void print_binary( char *data, size_t length )
{
for ( size_t i = 0; i < length; i += 16 )
{
int bytes_in_line = length - i >= 16 ? 16 : length - i;
//print line in hexadecimal representation
for ( int j = 0; j < 16; j++ )
{
if ( j < bytes_in_line )
printf( "%02X ", data[i+j] );
else
printf( " " );
}
//add spacing between hexadecimal and textual representation
printf( " " );
//print line in textual representation
for ( int j = 0; j < 16; j++ )
{
if ( j < bytes_in_line )
{
if ( isprint( (unsigned char)data[i+j] ) )
putchar( data[i+j] );
else
putchar( 'X' );
}
else
{
putchar( ' ' );
}
}
putchar( '\n' );
}
}
int main( void )
{
char *text = "This is a string with the unprintable backspace character \b.";
print_binary( text, strlen( text ) );
return 0;
}
The output of this program is the following:
54 68 69 73 20 69 73 20 61 20 73 74 72 69 6E 67 This is a string
20 77 69 74 68 20 74 68 65 20 75 6E 70 72 69 6E with the unprin
74 61 62 6C 65 20 62 61 63 6B 73 70 61 63 65 20 table backspace
63 68 61 72 61 63 74 65 72 20 08 2E character X.
As you can see, the function print_binary printed the data in both hexadecimal representation and textual representation, 16 bytes per line, and it correctly replaced the non-printable backspace character with the placeholer 'X' character when printing the textual representation.
Wrong printf conversion format specifier
The line
printf("\nSize of message_body is %d and message_body is \n%s\n", strlen(message_body), message_body);
is wrong. The return type of strlen is size_t, not int. The correct printf conversion format specifier for size_t is %zu, not %d. Using the wrong format specifier causes undefined behavior, which means that it may work on some platforms, but not on others.
Concatenating string with binary data
The following lines are wrong:
char *message = (char *)malloc(strlen(message_body) + strlen(message_footer) + fileLength);
strcat(message, message_body);
memcpy(message, fileData, fileLength);
memcpy(message, message_footer, strlen(message_footer));
The function strcat requires both function arguments to point to null-terminated strings. However, the first function argument is not guaranteed to be null-terminated. I suggest that you use strcpy instead of strcat.
Also, in your question, you correctly stated that the file binary data should be appended to the string. However, that is not what the line
memcpy(message, fileData, fileLength);
is doing. It is instead overwriting the string.
In order to append binary data to a string, you should only overwrite the terminating null character of the string, for example like this:
memcpy( message + strlen(message), fileData, fileLength );

Getting MAC address in c and writing it to a txt file

Following is my code. In this program I use system function and passe a command line argument to get the mac address of the pc and then write it into the txt file. txt file is creating successfully. But When I try to open the txt file which was created it wont show anything. It show letter M and some blank spaces. Any idea why is this happening ? Thank you.
#include<stdio.h>
int main()
{
system("wmic nic where (AdapterTypeId=0 AND netConnectionStatus=2) get MACAddress >macaddress.txt");
FILE * fpointer=fopen("macaddress.txt","r");
char buffer[500];
while(!feof(fpointer)){
fgets(buffer,500,fpointer);
puts(buffer);
}
fclose(fpointer);
}
This will do what you want, but if instead of just printing the contents of the file you actually want to do something with it and you need the text as ASCII you'll need to perform that conversion yourself from wide characters.
Since this particular file is just normal letters and numbers text you can convert the wide string to narrow with sprintf.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
system("wmic nic where (AdapterTypeId=0 AND netConnectionStatus=2) get MACAddress > macaddress.txt");
//Binary mode tells fgetws to read wide characters instead of multi-byte.
FILE * fp = fopen("macaddress.txt", "rb");
if (fp)
{
wchar_t buffer[500] = { 0 };
fread(buffer, 1, 2, fp); //read and discard BOM
while (fgetws(buffer, 500, fp))
{
// %ls means the parameter is a wide string.
// %S also works in Visual Studio
printf("%ls", buffer);
//Convert wide characters to ASCII
//This assumes the wide characters are all in the ASCII range
char ascii[500] = { 0 };
sprintf(ascii, "%ls", buffer);
printf("%s", ascii);
}
fclose(fp);
}
return 0;
}
It is not an ASCII encoded file. Here is a dump
0 1 2 3 4 5 6 7 8 9 A B C D E F
0000:0000 FF FE 4D 00 41 00 43 00 41 00 64 00 64 00 72 00  ■M.A.C.A.d.d.r.
0000:0010 65 00 73 00 73 00 20 00 20 00 20 00 20 00 20 00 e.s.s. . . . . .
0000:0020 20 00 20 00 20 00 20 00 0D 00 0A 00
etc so as not to reveal my MAC address.
Note too it contains zeros which will terminate any string output after reading with fgets.
My text editor (Notepad++) shows the correct content because it sets the right text format automatically.

How would you read from a text file in C if you know the character coding, then display it on the console?

Consider this example in Java:
public final class Meh
{
private static final String HELLO = "Hello world";
private static final Charset UTF32 = Charset.forName("UTF-32");
public static void main(final String... args)
throws IOException
{
final Path tmpfile = Files.createTempFile("test", "txt");
try (
final Writer writer = Files.newBufferedWriter(tmpfile, UTF32);
) {
writer.write(HELLO);
}
final String readBackFromFile;
try (
final Reader reader = Files.newBufferedReader(tmpfile, UTF32);
) {
readBackFromFile = CharStreams.toString(reader);
}
Files.delete(tmpfile);
System.out.println(HELLO.equals(readBackFromFile));
}
}
This program prints true. Now, some notes:
a Charset in Java is a class wrapping a character coding, both ways; you can get a CharsetDecoder to decode a stream of bytes to a stream of characters, or a CharsetEncoder to encode a stream of characters into a stream of bytes;
this is why Java has char vs byte;
for historical reasons however, a char is only a 16bit unsigned number: this is because when Java was born, Unicode did not define code points outside of what is now known as the BMP (Basic Multilingual Plane; that is, any code points defined in range U+0000-U+FFFF, inclusive).
With all this out of the way, the code above performs the following:
given some "text", represented here as a String, it first applies a transformation of this text into a byte sequence before writing it to a file;
then it reads back that file: it is only a sequence of bytes, but then it applies the reverse transformation to find back the "original text" stored in it;
note that CharStreams.toString() is not in the standard JDK; this is a class from Guava.
Now, as to C... My question is as follows:
discussing the matter on the C chat room, I have learned that the C11 standard has, with <uchar.h>, what seems to be appropriate to store a Unicode code point, regardless of the encoding;
however, there doesn't seem to be the equivalent of Java's Charset; another comment on the chat room is that with C you're SOL but that C++ has codecvt...
And yes, I'm aware that UTF-32 is endianness-dependent; with Java, that is BE by default.
But basically: how would I program the above in C? Let's say I want to program the writing side or reading side in C, how would I do it?
In C, you'd typically use a library like libiconv, libunistring, or ICU.
If you only want to process UTF-32, you can directly write and read an array of 32-bit integers containing the Unicode code points, either in little or big endian. Unlike UTF-8 or UTF-16, a UTF-32 string doesn't need any special encoding and decoding. You can use any 32-bit integer type. I'd prefer C99's uint32_t over C11's char32_t. For example:
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
// Could also contain non-ASCII code points.
static const uint32_t hello[] = {
'H', 'e', 'l', 'l', 'o', ' ',
'w', 'o', 'r', 'l', 'd'
};
static size_t num_chars = sizeof(hello) / sizeof(uint32_t);
const char *path = "test.txt";
FILE *outstream = fopen(path, "wb");
// Write big endian 32-bit integers
for (size_t i = 0; i < num_chars; i++) {
uint32_t code_point = hello[i];
for (int j = 0; j < 4; j++) {
int c = (code_point >> ((3 - j) * 8)) & 0xFF;
fputc(c, outstream);
}
}
fclose(outstream);
FILE *instream = fopen(path, "rb");
// Get file size.
fseek(instream, 0, SEEK_END);
long file_size = ftell(instream);
rewind(instream);
if (file_size % 4) {
fprintf(stderr, "File contains partial UTF-32");
exit(1);
}
if (file_size > SIZE_MAX) {
fprintf(stderr, "File too large");
exit(1);
}
size_t num_chars_in = file_size / sizeof(uint32_t);
uint32_t *read_back = malloc(file_size);
// Read big endian 32-bit integers
for (size_t i = 0; i < num_chars_in; i++) {
uint32_t code_point = 0;
for (int j = 0; j < 4; j++) {
int c = fgetc(instream);
code_point |= c << ((3 - j) * 8);
}
read_back[i] = code_point;
}
fclose(instream);
bool equal = num_chars == num_chars_in
&& memcmp(hello, read_back, file_size) == 0;
printf("%s\n", equal ? "true" : "false");
free(read_back);
return 0;
}
(Most error checks omitted for brevity.)
Compiling and running this program:
$ gcc -std=c99 -Wall so.c -o so
$ ./so
true
$ hexdump -C test.txt
00000000 00 00 00 48 00 00 00 65 00 00 00 6c 00 00 00 6c |...H...e...l...l|
00000010 00 00 00 6f 00 00 00 20 00 00 00 77 00 00 00 6f |...o... ...w...o|
00000020 00 00 00 72 00 00 00 6c 00 00 00 64 |...r...l...d|
0000002c

Getting error "The capture file appears to be damaged or corrupt. (pcap: File has 1847605831-byte packet, bigger than maximum of 65535)"

I am getting error when i am trying to dump a packet in pcap file.
{
unsigned char *ofilename = "packet.pcap";
pcap_t *fp;
pcap_dumper_t *dumpfile;
const struct pcap_pkthdr *header;
fp = pcap_open_dead(DLT_RAW,256);
if(fp != NULL)
{
dumpfile = pcap_dump_open(fp, ofilename);
if(dumpfile == NULL)
{
printf("\nError opening output file\n");
return;
}
pcap_dump((u_char *)dumpfile,header,data);
pcap_close(fp);
pcap_dump_close(dumpfile);
}
}
HERE data is a u8 data[256].. its 256 byte data.. which has the packet bytes like this
FF FF FF FF FF FF 00 50 56 A8 11 39 81 00 0F FC 81 00 1F FC 08 06 00 01 08 00 06 04 00 01 00 50 56 A8 11 39 65 2B 01 0A 00 00 00 00 00 00 65 2B
But when i open packet.pcap i am getting "The capture file appears to be damaged or corrupt. (pcap: File has 1847605831-byte packet, bigger than maximum of 65535)"
Could someone pls help me on this whats going wrong
Kindly install "pcapfix" on Linux and run it on the corrupt file as follows
$ pcapfix -d 'file / file path here'
This will fix it.
Try something such as
{
unsigned char *ofilename = "packet.pcap";
pcap_t *fp;
pcap_dumper_t *dumpfile;
struct pcap_pkthdr header;
fp = pcap_open_dead(DLT_RAW,256);
if(fp != NULL)
{
dumpfile = pcap_dump_open(fp, ofilename);
if(dumpfile == NULL)
{
printf("\nError opening output file\n");
return;
}
header.caplen = 256; /* or however many bytes actually contain packet data */
header.len = 256; /* or however many bytes actually contain packet data */
gettimefoday(&header.ts); /* I'm assuming this is on some flavor of UN*X */
pcap_dump((u_char *)dumpfile,&header,data);
pcap_close(fp);
pcap_dump_close(dumpfile);
}
}
For one thing, just because a function takes an argument of type "{something} *", that doesn't mean you should pass to it a variable of type "{something} *". You must pass it a value of type "{something} *", but it must be a valid value, i.e. it must point to something.
An uninitialized variable of type "{something} ``*", which is what you have in your code, doesn't point to anywhere valid.
However, if you declare a variable of type "{something}", rather than "{something} *", you can use the & operator on that variable to get a value of type "{something} *" that points to the variable.
Then, as indicated, you have to give that variable a value if you're passing it to pcap_dump(). You have to set the len and caplen members of a struct pcap_pkthdr; the caplen member must be equal to the actual number bytes of packet data (which might be less than the size of the array if the packet isn't, in your case, exactly 256 bytes long), and the len member must be at least that value; len would only be bigger than caplen if the packet came from a capture done with a "snapshot length" value that discarded everything in the packet past a certain point, which isn't the case here, so len should be equal to caplen.
You probably also want to set the time stamp of the packet; I'm assuming you're running on some form of UN*X here, so you can use gettimeofday() to get the current time. If this is Windows with WinPcap, you'll probably have to do something else.
(header must not be const here, as you have to set it. It doesn't have to be const; it's const in the declaration of pcap_dump(), but that just means that pcap_dump() won't change it, so you can pass it a pointer to something that's const; you don't have to pass it something that'sconst`.)

C Convert String to Ints Issue

I'm trying to parse some input on an embedded system.
I'm expecting something like this:
SET VARNAME=1,2,3,4,5,6,7,8,9,10\0
When I'm converting the separate strings to ints, both atoi() and strtol() seem to be returning 0 if the string begins with 8.
Here is my code:
char *pch, *name, *vars;
signed long value[256];
int i;
#ifdef UARTDEBUG
char convert[100];
#endif
if(strncmp(inBuffer, "SET",3)==0)
{
pch = strtok(inBuffer," ");
pch = strtok(NULL," ");
name = strtok(pch, "=");
vars = strtok(NULL,"=");
pch = strtok(vars,",");
i = 0;
while(pch != NULL)
{
value[i] = atoi(pch);
#ifdef UARTDEBUG
snprintf(convert, sizeof(convert), "Long:%d=String:\0", value[i]);
strncat(convert, pch, 10);
SendLine(convert);
#endif
i++;
pch = strtok(NULL,",");
// Check for overflow
if(i > sizeof(value)-1)
{
return;
}
}
SetVariable(name, value, i);
}
Passing it:
SET VAR=1,2,3,4,5,6,7,8,9,10\0
gives the following in my uart debug:
Long:1=String:1
Long:2=String:2
Long:3=String:3
Long:4=String:4
Long:5=String:5
Long:6=String:6
Long:7=String:7
Long:0=String:8
Long:9=String:9
Long:10=String:10
UPDATE:
I've checked the inBuffer both before and after 'value[i] = atoi(pch);' and it's identical and appears to have been split up to the right point.
S E T V A R 1 2 3 4 5 6 7 8 9 , 1 0
53 45 54 00 56 41 52 00 31 00 32 00 33 00 34 00 35 00 36 00 37 00 38 00 39 2c 31 30 00 00 00 00
UPDATE 2:
My UARTDEBUG section currently reads:
#ifdef UARTDEBUG
snprintf(convert, 20, "Long:%ld=String:%s", value[i], pch);
SendLine(convert);
#endif
If I comment out the snprintf() line, everything works perfectly. So what's going on with that?
can't you try to write your own atoi?
it's like ten lines long and then you can debug it easily (and check where the problem really is)
'0' = 0x30
'1' = 0x31
and so on, you just need to do something like
string[x] - 0x30 * pow(10, n)
for each digit you have
Not related, but
if(i > sizeof(value)-1)
{
return;
}
should be
if(i == sizeof(value)/sizeof(value[0]) )
{
return;
}
May be the cause of the problem if other pieces of code do the overflow checking in the wrong way and because of that they overwrite part of your string
I've just tried compiling and running your sample code on my own system. The output is correct (i.e. '8' appears where it should be in the output string) which indicates to me that something else is going on outside of the scope of the code you've provided to us.
I'm going to go out on a limb and say that one of your variables or functions is trampling your input string or some other variable or array. SendLine and SetVariable are places to look.
But more importantly, you haven't given us the tools to help you solve your problem. When asking people to help you debug your program, provide a simple test case, with full source, that exemplifies the problem. Otherwise, we're left to guess what the problem is, which is frustrating for us and unproductive for you.
atoi returns 0 for something that it can't render as numeric -- this is just a hunch, but have you tried dumping the binary representation of the string (or even checking that the string lengths match up)?

Resources