Reading a string is not going properly - c

Hey guys, i'm working on a program that gets a postfix expression and calculates it..
I have two functions:
Converts infix to postfix
Calculate the postfix
When I try small expressions, like 1+1 or (1+1)*1, it works fine
but when i use all the operands I get something nasty,
Here is the example:
2*2/2+1-1
gets something like:
222/*11-+T_CHECKÖÐ7?█Ã
If you see, the expression is right until the 'T'
I believe it's some parameter mistake, so i'll put the header and return values here
1st)
char* convert(char *infix);
char *post = (char *)malloc(sizeof(char)*tamP);
return post;
2nd)
int evaluate(char *postfix)
while (*postfix != '\0')
return result;
Caller)
char* post = convert(infix);
result = evaluate(post);
Thanks

That kind of weird string looks more like a buffer overflow error. You are likely overwriting the null-terminator, so when the string is printed (or later used), it keeps going until it finds one, examining random program memory until it gets there.
Check that all of your string manipulations are correct.

It is possible that you are not adding the '\0' character at the end of 'post' (after the last sensible character) in the convert(char*) function. That's one reason I can think of.
Try setting the complete string to '\0' before you do anything with it:
memset(post, 0, tamP);
should do.

Related

Why can't I access the next element in a string when I increment the pointer by one?

I'm trying to increment a pointer to a string by hand using the dereference operator like I've seen it work in the while loop I have bellow. It works for the first character, but when I try to increment the pointer by hand like it is in the while loop, it doesn't work and I get back garbage. Could someone please tell me what I'm not understanding? This code works the way I expect it.
char *pointToString = "some string or something";
printf("%c\n", *pointToString); // this returns the letter 's'
while(*pointToString != '\0'){
printf("%c", *pointToString);
*pointToString++;
}
This works and prints out 's' and then the string "some string or something", but why can't I access the second element of the string if I increment it by hand? When I do this, I get back garbage.
printf("%c\n", *pointToString+1);
This returns something other than the letter 'o'. I also tried this, but still got garbage:
printf("%c\n", *pointToString+sizeof(char));
I'm not sure if that's correct but I figured that I'm incrementing a pointer like I did in the while loop:
*pointToString++;
So why couldn't I do that by itself?
You cannot access the next element using the expression
printf("%c\n", *pointToString+1);
because the unary operator * has higher precedence than binary +. First, the current character is accessed; then, 1 is added to it. Proper use of parentheses will fix this problem:
printf("%c\n", *(pointToString+1));
Reference: Operator precedence table in C.
From my understanding, this should be your fix:
*(pointToString++); // Iterates first, and then has the pointer point to the correct value
This is what's happening in your one line:
*pointToString++; // Points to the value first and then iterates.
Hope this helps.

Confusions about if statement and strcmp with Strings

Here, I need some help in understanding the strings. I have a buff, which is flushed and then passed to a UART function. This buffer is now updated nad holding some value. I need to check the 5th byte of the buffer. What confuses me, I have written in code below.
Please take a look.
int main()
{
char buff[8];
memset(buff,0,8);
/*
This buff is used by some UART function, and hence is updated by UART
This buff now holds some data. And now, I need to check the 5th byte it is holding.
*/
if(buff[4]==0x04) //will this work? or I need to use if(strcmp(buff[4],0x04)) ???
{
//Do some functionality, for an example
printf("True");
}
else
printf("False");
return 0;
}
Your code is correct, yes.
Using strcmp() for this would only work if you know that the '\x04' character is followed by a '\0' string terminator. Since it looks like binary data, it would be very strange to use strcmp().
You are not in any way comparing "strings", so using == is fine. In C, a "string" means "a (pointer to a) 0-terminated array of char". That is not waht you're dealing with, so any lessons learned about how to deal with strings don't apply.

double pointer arithimethic, traversing chars of array string

Please help me understand what I am doing wrong with my double pointer arithmetic. I know I clearly doing something incorrect but what? Look at the line where I marked, "bad pointer". My intuition told me that this should work, but I guess not. Programmed in C.
/*
*This function searches for prefixes within the string array.
*#param stringArray array containing strings
*#param searchPrefix a string or characters to search for at beginning of string
*#return void
*/
void prefixSearch(char* stringArray[SIZE], char* searchPrefix){
int count = strlength(searchPrefix);//size of the prefix search
while(count > 0){
if(**stringArray == *searchPrefix){
printf("%c match %c\n", **stringArray, *searchPrefix);
**stringArray++;//want to move to next character, instead get bad pointer.
*searchPrefix++;//moves to next char
}else{
stringArray++;//no match, go to next string
}
count--;//decrement
}
}
The * and ++ operators have the same precedence, and right-to-left associativity, so the line that's not working parses like this:
*(*(stringArray++));
I don't actually understand your code, but that can't be what you intended since the dereference operators have no effect. Presumably you wanted this instead:
(**stringArray)++;
You have to move to next character so
use
(*stringArray)++ instead of **stringArray++
And
searchPrefix++ instead of *searchPrefix++

Proper use of strcat() in C

I have an archive file that looks like this:
!<arch>
file1.txt/ 1350248044 45503 13036 100660 28 `
hello
this is sample file 1
Now in here, the number 28 in the header is the file1.txt size. To get that number, I use:
int curr_char;
char file_size[10];
int int_file_size;
curr_char = fgetc(arch_file);
while(curr_char != ' '){
strcat(file_size, &curr_char);
curr_char = fgetc(arch_file);
}
// Convert the characters to the corresponding integer value using atoi()
int_file_size = atoi(file_size);
However, values in the file_size array change every time I run my code. Sometimes it's correct, but mostly not. Here are some examples of what I get for file_size:
?28`U
2U8U
28 <--- Correct!
pAi?28
I believe the problem is with my strcat() function, but not sure. Any help would be appreciated.
You shouldn't read the file character wise. There are higher level functions doing this. As larsmans already pointed out, you can use fscanf() for this task:
fscanf(arch_file, "%d", &int_file_size);
&curr_char is an int*, so you're copying over the bits of an int as if they represented a string.
You should be using scanf.
The expression &curr_char points to a single character (well, actually an integer as that's how you declared it). strcat looks for a string, and string as you should know are terminated by a '\0' character. So what strcat does in your case is use the &curr_char pointer as the address of a string and looks for the terminator. Since that is not found weird stuff will happen.
One way of solving this is to make curr_char an array, initialized to zero (the string terminator character) and read into the first entry:
char curr_char[2] = { '\0' }; /* Will make all character in array be zero */
...
curr_char[0] = fgetc(...);
There is also another problem, and that is that you are trying to concatenate into a string that is not initialized. When running your program, the array file_size can contain any data, it's not automatically zeroed out. This leads to the weird characters before the number. This is solved partially the same way as the above problem, by initializing the array:
char file_size[10] = { '\0' };

Pointer mystery/noobish issue

I am originally a Java programmer who is now struggling with C and specifically C's pointers.
The idea on my mind is to receive a string, from the user, on a command line, into a character pointer. I then want to access its individual elements. The idea is later to devise a function that will reverse the elements' order. (I want to work with anagrams in texts.)
My code is
#include <stdio.h>
char *string;
int main(void)
{
printf("Enter a string: ");
scanf("%s\n",string);
putchar(*string);
int i;
for (i=0; i<3;i++)
{
string--;
}
putchar(*string);
}
(Sorry, Code marking doesn't work).
What I am trying to do is to have a first shot at accessing individual elements. If the string is "Santillana" and the pointer is set at the very beginning (after scanf()), the content *string ought to be an S. If unbeknownst to me the pointer should happen to be set at the '\0' after scanf(), backing up a few steps (string-- repeated) ought to produce something in the way of a character with *string. Both these putchar()'s, though, produce a Segmentation fault.
I am doing something fundamentally wrong and something fundamental has escaped me. I would be eternally grateful for any advice about my shortcomings, most of all of any tips of books/resources where these particular problems are illuminated. Two thick C books and the reference manual have proved useless as far as this.
You haven't allocated space for the string. You'll need something like:
char string[1024];
You also should not be decrementing the variable string. If it is an array, you can't do that.
You could simply do:
putchar(string[i]);
Or you can use a pointer (to the proposed array):
char *str = string;
for (i = 0; i < 3; i++)
str++;
putchar(*str);
But you could shorten that loop to:
str += 3;
or simply write:
putchar(*(str+3));
Etc.
You should check that scanf() is successful. You should limit the size of the input string to avoid buffer (stack) overflows:
if (scanf("%1023s", string) != 1)
...something went wrong — probably EOF without any data...
Note that %s skips leading white space, and then reads characters up to the next white space (a simple definition of 'word'). Adding the newline to the format string makes little difference. You could consider "%1023[^\n]\n" instead; that looks for up to 1023 non-newlines followed by a newline.
You should start off avoiding global variables. Sometimes, they're necessary, but not in this example.
On a side note, using scanf(3) is bad practice. You may want to look into fgets(3) or similar functions that avoid common pitfalls that are associated with scanf(3).

Resources