Comparing "" and "" in C - c

So I have the following test code:
#include <string.h>
#include <stdio.h>
int main(int argc, char* argv[]){
int retVal = strcmp("", "");
printf("%d\n", retVal);
return 0;
}
And for me, it always seems print out 0, i.e. "" and "" are always equal one another. But I'm curious. Is this something guaranteed by strcmp, or does it have the potential to vary from implementation to implementation? Maybe I'm just being paranoid, but I've worked on enough strange systems to know the perils of differing implementations.
UPDATE:
I've decided to clarify to justify my paranoia. What I'm really doing in my program is more akin to this:
#include <string.h>
#include <stdio.h>
int doOperation(const char* toCompare){
//do stuff in here
int compResult = strcmp(toCompare, "");
//do more stuff depending on compResult
}
int main(int argc, char* argv[]){
const char* myString = "";
doOperation(myString);
return 0;
}
I want to make sure things in doOperation will proceed correctly. Note that this is just an example. In my doOperation function I'm not going to actually know that the value of toCompare.

A string is equal to another string if all the characters before the NULL terminator of both strings are exactly the same. Since "" has no characters, it fits that definition when compared with "".

No it won't vary with different implementations as C code is compiled to machine specific code and strcmp() will do the same in all platforms. You will get the same result everywhere. I also agree with Seth Carnegie's answer.

Related

How to concatenate char pointers using strcat in c? [duplicate]

This question already has answers here:
Why do I get a segmentation fault when writing to a "char *s" initialized with a string literal, but not "char s[]"?
(19 answers)
Closed 3 years ago.
I'm learning pointers in C, using Linux. I'm trying to use the strcat function, but it doesn't work and I don't understand why.
I'm passing a username to the main as an argument because I need to concatenate and put a number 1 in the first position of this username. For example if the I got as argument username123 I need to convert this to 1username123
I got this code:
#include <stdio.h>
#include <string.h>
int main(int argc, char *arg[]){
const char *userTemp;
char *finalUser;
userTemp = argv[1]; //I got the argument passed from terminal
finalUser = "1";
strcat(finalUser, userTemp); //To concatenate userTemp to finalUser
printf("User: %s\n",finalUser);
return 0;
}
The code compiles, but I got a segmentation fault error and doesn't know why. Can you please help me going to the right direction?
It is undefined behaviour in C to attempt to modify a string literal (like "1"). Often, these are stored in non-modifiable memory to allow for certain optimisations.
Let's leave aside for the moment the fact that your entire program can be replaced with:
#include <stdio.h>
int main(int argc, char *argv[]){
printf("User: 1%s\n", (argc > 1) ? argv[1] : "");
return 0;
}
The way you ensure you have enough space is to create a buffer big enough to hold whatever you want to do. For example:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]){
// Check args provded.
if (argc < 2) {
puts("User: 1");
return 0;
}
// Allocate enough memory ('1' + arg + '\0') and check it worked.
char *buff = malloc(strlen(argv[1]) + 2);
if (buff == NULL) {
fprintf(stderr, "No memory\n");
return 1;
}
// Place data into memory and print.
strcpy(buff, "1");
strcat(buff, argv[1]);
printf("User: %s\n", buff);
// Free memory and return.
free(buff);
return 0;
}
What you shouldn't do is to allocate a fixed size buffer and blindly copy in the data provided by a user. That's how the vast majority of security problems occur, by people overwriting buffers with unexpected data.
I'm trying to use the strcat function, but it doesn't work and I don't understand why.
For starters, you really shouldn't use strcat(). Use strlcat() instead. The "l" version of this and other functions take an extra parameter that let you tell the function how large the destination buffer is, so that the function can avoid writing past the end of the buffer. strcat() doesn't have that parameter, so it relies on you to make sure the buffer is large enough to contain both strings. This is a common source of security problems in C code. The "l" version also makes sure that the resulting string is null-terminated.
The code compiles, but I got a segmentation fault error and doesn't know why.
Here's the prototype for the function: char *strcat( char *dest, const char *src );
Now, you're calling that essentially like this: strcat("1", someString);. That is, you're trying to append someString to "1", which is a string constant. There's no extra room in "1" for whatever string is in someString, and because you're using a function that will happily write past the end of the destination buffer, your code is effectively writing over whatever happens to be in memory next to that string constant.
To fix the problem, you should:
Switch to strlcat().
Use malloc() or some other means to allocate a destination buffer large enough to hold both strings.
Unlike in other languages there is no real string type in C.
You want this:
#include <stdio.h>
#include <string.h>
int main(int argc, char *arg[]){
const char *userTemp;
char finalUser[100]; // finalUser can contain at most 99 characters
userTemp = argv[1]; //I got the argument passed from terminal
strcpy(finalUser, "1"); // copy "1" into the finalUser buffer
strcat(finalUser, userTemp); //To concatenate userTemp to finalUser
printf("User: %s\n",finalUser);
return 0;
}
or even simpler:
#include <stdio.h>
#include <string.h>
int main(int argc, char *arg[]){
char finalUser[100]; // finalUser can contain at most 99 characters
strcpy(finalUser, "1"); // copy "1" into the finalUser buffer
strcat(finalUser, argv[1]); //To concatenate argv[1] to finalUser
printf("User: %s\n",finalUser);
return 0;
}
Disclaimer: for the sake of brevity this code contains a fixed size buffer and no check for buffer overflow is done here.
The chapter dealing with strings in your C text book should cover this.
BTW you also should check if the program is invoked with an argument:
int main(int argc, char *arg[]){
if (argc != 2)
{
printf("you need to provide a command line argument\n");
return 1;
}
...
You're missing some fundamentals about C.
finalUser = "1";
This is created in "read-only" memory. You cannot mutate this. The first argument of strcat requires memory allocated for mutation, e.g.
char finalUser[32];
finalUser[0] = '1';

Retrieve information using stack buffer overflow (C)

I found one interesting exercises on the net, it states that the specific input can overflow the buffer in such a way that the 'secret' will be printed to stdout.
I tried to figure it out by my self but I haven't done well.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void get_name(char *name, char *pr) {
char local[20];
printf("%s:",pr);
gets(local);// BUG
strncat(name,local,20);
}
int foo () {
char name[28]="Hello..";
char secret[12]="TOP SECRET";
char buf[24];
char n1[]="Enter your name";
char n2[]="Enter Secret code";
get_name(name,n1);
memset(buf, 0, sizeof(buf));
// Lets ONLY use strncpy for better control!!!
strncpy(buf, name, sizeof(buf));//BUG
printf("%s\n", buf);
memset(name,0,sizeof(name));
get_name(name, n2);
if (strncmp(secret,name,10)==0)
printf("Welcome and %s\n",buf);
else {printf("Wrong code, better try again..\n");}
return 0;
}
int main(int argc, char **argv)
{
foo();
printf("Bye\n");
return 0;
}
There is no way to know what the outcome of such buffer overflows will do. You can't know or assume what memory they will overwrite. Most likely they will only cause some sort of run-time crash. Any exploit would have to have a very specific system in mind. Which means that nobody would be able to answer your question without knowing the details of a given system.
What your "random internet person" is aiming for, is likely to overwrite the null termination of Hello.. with some garbage, so that the "TOP SECRET" string will get printed along with it. You can't assume that those two strings are allocated adjacently, however. You could try to type 28 letter long input to gets and see what happens... there are no guarantees of any given behavior. On my computer it does nothing exciting apart from printing some garbage. Reverse-engineering of my binary reveals that that's because the arrays are indeed not allocated adjacently.
In addition, your comments about strncpy are misguided, strncpy is dangerous and should be avoided, see this.

While (isspace(array))

How can I make the "while" function stop when the i position is a blank space?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
int main ()
{
int i,t;
char array[20];
t=strlen(array);
for (i=0;i<=t;i++)
{
if(isspace(expressio[i])){
while (expressio[i+1]!=isspace(expressio[i+1]))
i=i+1;
if (isspace(expressio[i+1]))
{ code follows here...}
Can I do it like this?
I am programming in C.
No, you can't do this.
while (expressio[i+1]!=isspace(expressio[i+1]))
makes no sense. expressio[i+1] is a character, while isspace(expressio[i+1]) is either 1 or 0. You compare apples to oranges.
Besides,
char array[20];
t=strlen(array);
makes no sense, either. If you write a string to the array, then strlen would return the length of that string. Calling strlen before initializing array is useless (and it may return just anything).

How to compose characters into a single string in memory?

I am working on a school assignment and I need a little bit of help.
My question is, how can I compose characters that are read in from a file into a single string of memory. Here is what i have so far.
My Code:
#include <stdio.h>
#include <stdlib.h>
char myString;
int main(int argc, char *argv[]){
FILE* fin;
char ch;
fin=fopen(argv[1],"r");
while((ch=fgetc(fin))!=EOF){
printf("%c\n", ch);
}
fclose(fin);
return 0;
}
My teacher said the last part of main is to be:
putchar(ā€˜\nā€™);
printf( myString );
return 0;
}
But I'm not sure how to put that within my code. Thank you ahead of time, Im also not looking to be just given the answer if you could help me work it out that would be great thank you again.
Updated code:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
FILE* fin;
int i;
char myString[3];
fin=fopen(argv[1],"r");
while(fgets(myString,sizeof(myString), fin)){
putchar('\n');
printf("%c\n", myString[i]);
}
fclose(fin);
return 0;
}
Im unsure if this code is exactly correct. It prints out the items within the file and puts a space between them. and there is an array being used for the string.
Im also not looking to be just given the answer
Fine.
Define a char array (mystring) large enough to hold your string
Define a counter to keep track of the position in the array
At each step store ch into the array
Remember to 0-terminate it (store 0 as the last element).
Things to note:
You will need to learn about realloc and grow the storage as you go if your program is to read arbitrarily long input. Better leave that for later
It's generally unsafe to printf(dynamicstr). What if it contains a "%d" ? It's better to printf("%s", dynamicstr).
You get to learn about memcpy and malloc. They are your friends.
--Jason
You need to read the applicable part of your textbook that explains what a "string" is in C. Without you understanding that, there's almost no way to answer your question without simply doing it for you.
A C "string" is a contiguous chunk of memory containing chars and is NULL terminated. You'll need to allocate that then place the characters into it as you read them from the file. Note that you have to make sure you don't go beyond the memory you've allocated while doing so, this is called a "buffer overflow".
#include <stdio.h>
#include <stdlib.h>
char* myString;
int main(int argc, char *argv[]){
FILE* fin;
fpos_t fsize = 0;
char ch;
char *pch;
fin=fopen(argv[1],"r");
fseek(fin,0,SEEK_END);
fgetpos(fin, &fsize);
rewind(fin);
pch = myString = (char*)malloc((fsize+1)*sizeof(char));
while((ch=fgetc(fin))!=EOF){
*pch++ = (char)ch;
}
*pch = '\0';
fclose(fin);
printf("%s", myString);//printf(myString);// need escape %
free(myString);
return 0;
}

how to assign a value to a string array?

for example
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char substr[10][20];
int main() {
substr[0] = "abc";
printf("%d", substr[0]);
}
of course above is wrong? how to do it? thanks
You can't assign strings like that in C. Instead, use strcpy(substr[0], "abc"). Also, use %s not %d in your printf
I hate giving 'full' answers to homework questions, but the only way to answer your question is to show you the answer to your problem, because it is so basic:
#include <stdio.h>
#include <string.h>
#define MAXLEN 20
char substr[10][MAXLEN];
int main(void) {
strncpy(substr[0], "abc", MAXLEN);
puts(substr[0]);
return 0;
}
Your code (as is) has several faults:
You are treating substr[0] as a string literal. You can't do that.
You were using printf formatters incorrectly. %s is for strings
You don't need to bother printf() to print a string
You should (in real code) watch out for buffer overflows, hence strncpy()
If main() doesn't want / need argc and argv, its arguments should be void
main() should return a value, as its return type is int
You aren't using anything out of <stdlib.h>, why include it?
I suggest researching string literals, the functions available in <string.h> as well as format specifiers.
Also note, I am not checking the return of strncpy(), which is something you should be doing. That is left as an exercise for the reader.
Hope this helps:
void main(void)
{
char* string[10];
string[0] = "Hello";
}
Otherwise I think ya need to copy it by hand or use strcpy or the like to move it from one block of memory to another.

Resources