Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I was trying to copy the contents of 1 string to another (a into b) .
I deliberately took the second string(b) to be smaller than the 1st
one(a) .
I copied the contents of the first one into second
. I added WATCH on both of them . In the Debug tab , I found out that while
copying the original string gets destroyed and the new one also
DISPLAYED LARGER than its size.
#include<stdio.h>
int main()
{
char a[10]="What?";
char b[2];
int i;
for(i=0;i<6;i++)
{
b[i]=a[i];
}
printf("This is %s",a);
printf("\n this is b now: ",b);
return 0;
}
I have attached the screenshot for the same. I took a = a string of
size 10 . a="WHat?" then I took a string b[2]
After copying , I printed both a and b . I expected the output to be
, a = "WHat?" , b="WH" But the output is coming something else.(See
the screenshot)
Why did the original string get destroyed ? Has the pointer changed ? But I have made it a constant pointer .It can't be changed.
Here is the Screen shot to the problem I am facing :
https://www.dropbox.com/s/8xwxwb27qis8xww/sjpt.jpg
Please Help Somebody !!
You are copying 6 bytes into an array of two bytes, essentially invoking undefined behavior.
You are passing array b to printf with %s specifier that expects a null-terminated string, while b is most likely not null-terminated at that point, which is another undefined behavior.
Also, a null-terminated string that can fit into 2 bytes array can essentially have only one printable character, so you should not expect b to be "WH". At best, if you fix the copying, it can only be "W" as the second character will be a termination byte (\0). If you want to have two characters, either increase the array size to 3 to allow for null terminator, or simply do not use C strings and print out two bytes using "%c%c" format string.
As pointed out in other answers, you are writing outside the bounds of the array. The original string a changes because it happens to be exactly after b in memory as you can see in the debug window.
Before the loop, memory looks like this:
b a
|00|WHat?00000|
After the loop, memory looks like this:
b a
|WH|at?0?00000|
This explains why
a is changed
the original questionmark in a is still there (you only write 6 characters - two into the location reserved for b, 4 (including null terminator) into the location of a)
Of course this is undefined behavior as already mentioned by Vlad Lazarenko, but it explains the behavior for your compiler/settings/version/etc.
A constant pointer only exists for the compiler. It ensures that you cannot explicitly manipulate its data, but if you have memory leaks, nothing can be guaranteed.
What you're doing currently is very unsafe! It might work on Windows for some godforsaken reason, but don't do this!
The C standard library has special functions for working with strings and memory, strcpy for example is for copying character arrays. I suggest you learn more about how strings work and how you can manipulate them.
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 9 months ago.
Improve this question
I am new to C, I have written a very simple program to get the first name and surname, here is my code...
#include <stdio.h>
#include <conio.h>
int main(){
int num,bankpin;
char fn[20],sn[20];
printf("Welcome to authorization. We ill now begin the process");
printf("\nFirst, please enter your first name: ");
scanf(" %s",fn);
printf("\nEnter your surname: ");
scanf(" %s",sn);
printf("\nWelcome to the system %c %c",&fn,&sn);
return 0;
}
Welcome to authorization. We ill now begin the process
First, please enter your first name: A
Enter your surname: A
Welcome to the system α
Why is this strange "a" appearing on my screen instead of "A A"?
In fact it appears on my screen even if I try a different combination of letters
I have even tried recompiling the code
I'm guessing this is because you are trying to print &fn, which is a pointer, as char. You're basically telling the program to interpret the address o as a symbol code.
Try changing the
printf("\nWelcome to the system %c %c",&fn,&sn) to
printf("\nWelcome to the system %s %s",fn,sn)
Short answer
You are sending the array pointer's address as an argument, and telling printf to interpret it as a single char, resulting in undefined behavior. The fix is to replace the line
printf("\nWelcome to the system %c %c",&fn,&sn);
with
printf("\nWelcome to the system %s %s",fn,sn);
Long answer
The weird character is due to your code reading an unintended value, and trying to interpret it. If you run your code a few times, you will find that you don't always get this symbol, but many other ones, including nothing at all (seemingly). What is going here ?
The short answer is that you are misinforming the printf function by giving her a false symbol and a false value. Let's look at a similar example :
char myString[20] = "Hello!";
printf("%c", &myString);
In this snippet we create an array of characters, which actually means creating a pointer of char* type, and allocating its size (here to 20). Pointers are often confusing when starting with C, but they are in principle pretty simple : they are simply variables that, instead of containing a value, contain an address. Since arrays in C store their value sequentially, that is one after the other, it makes quite a lot of sense to have them be pointers : if you know where the array starts, and that its members are spaced evenly, it makes it quite easy to go over the array.
So since your array is a pointer, reading it directly will print something along the lines of "0x7ffc5a6dbb70". Putting '&' before it gives a very similar result : this operator consists in asking for the address of a variable, which is then in your code transmitted to the printf as an argument.
This doesn't make any sense there : a char is, in C, behind the scene, actually an integer variable with very small capacity, from 0 to 255 to be precise. For example the two lines in the following snippet produce the same result :
printf("%c", 'a');
printf("%c", 97);
Now you see what is happening in the original printf : the function is expecting to receive a very small integer to convert to one character, and instead receives an address, which is the reason why the output is so weird. Since addresses change basically at every run of the code, that is also the reason why the output changes very often.
You thus need to adapt the information in the printf function. First, inform that you wish to print a char array with the symbol "%s". This will make the function expect to receive a pointer to the first element of a char array, which it will then iterate over. Thus, as argument, you need to send this pointer, that you directly have in the form of the myString variable.
Thus running
char myString[20] = "Hello!";
printf("%s", myString);
prints 'Hello!', as expected :)
The funcion scanf is a little tricky, please delete the leading space, inside quotes only include what are you expecting to receive, ever.
scanf("%s",fn);
The printf function needs %s, same as scanf, to deal with string, later you don't need the & operator in this case.
printf("\nWelcome to the system %s %s",fn,sn);
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
Please explain this output. The problem is same with scanf. How can the array be reinitialized everytime?
Input:
HelloWorld
Tech
Output:
eo
Tech
TW
Code:
#include<stdio.h>
#include<string.h>
int main()
{ char c[1024]; int i,d=1;
gets(c);
printf("%c%c\n",c[d],c[d+5]);
gets(c);
puts(c);
printf("%c%c\n",c[0],c[4+d]);
return 0;
}
In C, strings are stored as null-terminated arrays of characters. This means that there are many ways to represent the same string: everything in the array of characters after the first null byte is ignored, as far as the value of the string is concerned.
When the first gets call reads HelloWorld, it stores the character 'H' in c[0], 'e' in c[1], …, 'd' in c[9] and 0 (that's a null byte, not '0') in c[10]. The contents of c[11] through c[1023] are unchanged.
When the second gets call reads Tech, it stores the character 'T' in c[0], 'e' in c[1], 'c' in c[2], 'h' in c[3] and 0 in c[4]. The contents of c[5] through c[1023] are unchanged. In particular, c[5] still has the value W that was set by the first gets call.
If you're used to high-level languages, you might expect that gets allocates new storage, or that doing what looks like a string access guarantees that you're actually accessing the string, but neither of these is true.
As you might guess from the fact that you pass an array of characters to gets, it merely writes to that array of characters, it doesn't allocate new storage. When gets reads a 4-byte string, it writes that 4-byte string plus the terminating null byte, and it doesn't touch whatever comes after those 5 bytes. In fact, gets doesn't even know the size of the array (which is why gets is practically unusable in practice and has been removed from the current version of the C language: if you input a line that's too long for the array, it will overwrite whatever comes after the array in memory).
c[5] accesses the element of the array c at position 5. This happens to be outside the string, but that's not relevant to how an array access operates. It's an array access, not a string access. C doesn't really have strings natively: it fakes them with arrays of characters. String manipulation functions treat their arguments as strings (i.e. they only look up to the first null byte). But an array access is just an array access, and it's up to the programmer not to access the string, or the array, out of bounds.
Please correct your indications. You may want to use 2, 3, 4 spaces, but 1 just looks wrong. I don't see any use of the string.h library.
The array is not cleared, but the 0..3 characters are replaced with the new ones and character on position 4 is \0. That's why you can read character from previously entered value at position 5 in this array.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
This program accept 5 string and print them.
here is the program:-
#include"stdio.h"
#include"conio.h"
void main(){
clrscr();
char s[5];
for(int i=0;i<5;i++){
scanf("%s", s[i]);
}
for(i=0;i<5;i++){
printf("\n\n%s", s[i]);
}
getch();
}
when i execute this program the output will be this
Click here to see the output of the program
but when i enter the string in different way it print wrong output
Click here to see the output of the program
You are reading a string into a char, or rather, the string you read starts at the char position i in s. As s is very short (and when i is 5 it is empty), there will be an overflow, causing undefined behavior.
You want to have an array of strings, not of chars, as Blue Pixy mentions in his comment, e.g. char s[5][32];.
Also turn warnings on. The i in the second for loop is not defined.
You've declared s as a 5-element array of char; each s[i] can store a single character value, not a string. Since you don't explicitly initialize each s[i], they contain an indeterminate value.
The argument corresponding to the %s specifier in scanf must have type char * (each s[i] has type char), and it must point to the first element of an array of char large enough to store the string contents (including the 0 terminator that marks the end of the string).
When you call
scanf( "%s", s[i] );
you're telling scanf to store the next sequence of non-whitespace characters to the address corresponding to the value stored in s[i], which is a) indeterminate and b) likely not valid. The resulting behavior is undefined, meaning pretty much anything can happen - your code may work as expected, it may crash outright, it may give you garbled output, it may corrupt other data, etc.
As written, s can store a string up to 4 characters long.
If you want to store an array of strings, then s needs to be a 2-dimensional array of char:
#define MAX_STRING_LENGTH 20 // or however long you expect your longest string to be
...
char s[5][MAX_STRING_LENGTH + 1];
Each s[i] can now store a string up to MAX_STRING_LENGTH characters. The rest of your code should now behave as expected.
This question already has answers here:
How do I determine the size of my array in C?
(24 answers)
Closed 6 years ago.
my professor has assigned a project where we need to make a reverse polish calculator in C (input in postscript syntax). I'm currently working on a method to find the length of the array of values I have scanned in (via .txt file). My current method is
int length(int list[]) {
int c = 0;
while(0 == 0) {
if(list[c] != '\0') {c++;}
else {break;}
}
return c;
}
and the call for it is
int sizeA = length(list);
printf("\n%d\n", sizeA);
It's currently only outputting the length as 0. Does anyone know why that might be and a fix to this method?
Thanks
The notion of "length" is a sort of tricky one in C (and low-level programming in general). If you have an array, the C compiler knows how large it is and provides an interface to the programmer to get that value in bytes: sizeof. The thing is, arrays are passed via pointers in C and determining the size via pointers is impossible without certain meta-information. Common methods to determine the length of an array are
appending an end marker to the array. Determining the length is simply a matter of iterating until the end marker is found and returning the number of iterations. Note that this renders the end marker's value unavailable for use as a value in the array.
just passing the size of the array around. Take the write system call as an example. Besides the file handle, it needs a pointer to the data and its length. Why its length as well? Because the pointer doesn't contain information about the length. So, either use a terminator like a null byte or pass the length explicitly. The former idea can be abandoned because the write system call is supposed to be generic; and to yield genericity, a null byte must be expected to be a possible value in the array, so it cannot be used as a terminator for reasons I uttered above.
Which one you actually end up using totally depends on the particular use case.
Apparently you decided to use the terminator-variant. \0 is the null byte, an ASCII character with code value 0x0. It's commonly used for terminating C-strings. strlen uses it to determine a C-string's length, for example. For int arrays, there is no such predefined terminator, so you need to come up with your own one. If you decide on \0, so be it, but I'd use the literal 0x0 instead because strictly-speaking, \0 is a character literal and that's just unfitting for ints.
To actually implement this, you'd need to append the terminating value to every int array, whose size you want to determine this way. Then write your function to get the length of such an int array just as you do, i.e., by iterating until the terminator is found.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Disclaimer: Been doing Java for a while, but new to C.
I have a program that I wrote, and I'm purposely trying to see what happens with different inputs and outputs.
#include <stdio.h>
int main() {
printf("whattup\n");
char str1[1], str2[1];
printf("Enter something: ");
scanf("%s", &str1);
printf("Enter something else: ");
scanf("%s", &str2);
printf("first thing: %s\n", str1);
printf("second thing: %s", str2);
}
This is the program flow:
whattup
Enter something: ahugestatement
Enter something else: smallertext
first thing: mallertext
Things I don't understand:
Why does "first thing" print out the str2?
Why does str2 have it's first letter cut off?
Why does "second thing:" not print out?
I made the char array with a size of 1, shouldn't it only hold 1 letter?
To answer your questions specifically, you'll have to keep in mind that what happens is very much implementation-specific. The specific behavior you're seeing doesn't have to hold true on all C implementations. This is what the C standard calls "undefined behavior". With that in mind:
Why does "first thing" print out the str2?
Why does str2 have it's first letter cut off?
You have allocated storage for two chars on the stack. The compiler allocates them next to each other, with str2 preceding str1 in memory. Therefore, after your first scanf, part of the stack will look like this:
str1 is allocated here
v
? a h u g e s t a t e m e n t \0
^
str2 is allocated here
Then, after the second scanf, the same part of memory will look like this:
str1 is allocated here
v
s m a l l e r t e x t \0 e n t \0
^
str2 is allocated here
In other words, the second input simply overwrites the first, since it goes beyond the bounds of the storage you allocated for it. Then, when you print out str1, it simply prints whatever is at the address of str1, which, as you can see in the figure above, is mallertext.
Why does "second thing:" not print out?
This is because of two effects interacting. For one thing, where you print str2, you do not end the output with a newline. stdout is normally line-buffered, which means that data written to it is not actually written to the underlying terminal until either A) a newline is written, B) you explicitly call fflush(stdout), or C) the program exits.
It would, therefore, print it when the program exited, but your program never exits. Since you overwrite parts of the stack that you don't manage, in this case you overwrite the return address from main, and therefore, when you return from main, your program promptly crashes, and thus never arrives to the point where it would flush stdout.
In the case of your program, the stack-frame layout of main looks like this (assuming AMD64 Linux):
RBP+8: Return address
RPB+0: Previous frame address
RBP-1: str1
RBP-2: str2
Since ahugestatement including its NUL terminator is 15 bytes, the 14 of those bytes that don't fit in str1 overwrite the entire previous frame address and 6 bytes of the return address. Since the new return address is entirely invalid, your program segfaults when the return from main jumps to an address that isn't even mapped in memory.
I made the char array with a size of 1, shouldn't it only hold 1 letter?
Yes, and it does. It's just that you clobber the memory that follows it.
As a general statement, scanf is not really a terribly useful function if you want to do even any most basic form of checking for illegal input. If you're hoping to do interactive input at all, it is almost always better to use something like fgets() instead and then parse the read input. fgets(), unlike scanf, takes an additional input for the size of the receiving buffer, and will then make sure to not write outside it.
You have to do the bounds checking in C, to make sure your buffers don't overflow. So your output is undefined. If you run that code many times, its bound to crash at some point because the overflown buffers will end up overwriting something important.
That's called buffer overflow. You allocated one character to hold your input, but you are writing beyond that (messing up the rest of your program's memory).
Unlike Java, the C compiler and runtime do not enforce array bounds. That is one of the main differences between "(memory-) managed languages" and low-level languages.
Your array only holds one character and the rest is out of bounds.
Access out of the range of an array is undefined and usually disastrous.