I'm extremely new to C and am doing a few problems I found in a book I bought. What is wrong with this program?
int main (void)
{
char text[50]='\0';
scanf ("%s", text);
printf("%c", text[49]);
printf("%s", text);
return 0;
}
char text[50]='\0';
is not valid. You could skip initialising text and just declare it
char text[50];
or you could initialise its first element
char text[50]={'\0'};
You're also missing an include of stdio.h and should really check that your scanf call read a string and could give it a max length for the string
if (scanf("%49s", text) == 1)
You want to get rid of:
printf("%c", text[49]);
as you have no idea what's at that memory location if the string is less than 49 chars long.
There is a difference of single quotes and double quotes in C.
double quotes means string
single quotes means character
Line 3 will not compile because the compiler wants you to assign a string to the array of characters.
You can do
char text[50]="\0";
which in effect fills all the 50 bytes with zeros.
You could also do
char text[50]="bla";
which fills the first 3 bytes with "bla" and the rest with zeros. At least my compiler does it like that.
You could also do nothing because you anyway fill it with user input just the next statement.
char text[50];
scanf ("%s", text);
But then you have a problem. Because the very next statement will give you random output if the user has entered a string with less than 49 characters. But if you initialize, well then you output the zero byte, which is also quite useless.
The main point however is to learn the different behaviour of C when dealing with an array of characters.
int main ()
{
char text[50]={'1','2','3','4'};
printf("%c", text[1]);
printf("%c",text[0]);
getch();
return 0;
}
do like this..
Related
For an instance if I store ABCDE from scanf function, the later printf function gives me ABCDE as output. So what is the point of assigning the size of the string(Here 4).
#include <stdio.h>
int main() {
int c[4];
printf("Enter your name:");
scanf("%s",c);
printf("Your Name is:%s",c);
return 0;
}
I'll start with, don't use int array to store strings!
int c[4] allocates an array of 4 integers. An int is typically 4 bytes, so usually this would be 16 bytes (but might be 8 or 32 or something else on some platforms).
Then, you use this allocation first to read characters with scanf. If you enter ABCDE, it uses up 6 characters (there is an extra 0 byte at the end of the string marking the end, which needs space too), which happens to fit into the memory reserved for array of 4 integers. Now you could be really unlucky and have a platform where int has a so called "trap representation", which would cause your program to crash. But, if you are not writing the code for some very exotic device, there won't be. Now it just so happens, that this code is going to work, for the same reason memcpy is going to work: char type is special in C, and allows copying bytes to and from different types.
Same special treatment happens, when you print the int[4] array with printf using %s format. It works, because char is special.
This also demonstrates how very unsafe scanf and printf are. They happily accept c you give them, and assume it is a char array with valid size and data.
But, don't do this. If you want to store a string, use char array. Correct code for this would be:
#include <stdio.h>
int main() {
char c[16]; // fits 15 characters plus terminating 0
printf("Enter your name:");
int items = scanf("%15s",c); // note: added maximum characters
// scanf returns number of items read successfully, *always* check that!
if (items != 1) {
return 1; // exit with error, maybe add printing error message
}
printf("Your Name is: %s\n",c); // note added newline, just as an example
return 0;
}
The size of an array must be defined while declaring a C String variable because it is used to calculate how many characters are going to be stored inside the string variable and thus how much memory will be reserved for your string. If you exceed that amount the result is undefined behavior.
You have used int c , not char c . In C, a char is only 1 byte long, while a int is 4 bytes. That's why you didn't face any issues.
(Simplifying a fair amount)
When you initialize that array of length 4, C goes and finds a free spot in memory that has enough consecutive space to store 4 integers. But if you try to set c[4] to something, C will write that thing in the memory just after your array. Who knows what’s there? That might not be free, so you might be overwriting something important (generally bad). Also, if you do some stuff, and then come back, something else might’ve used that memory slot (properly) and overwritten your data, replacing it with bizarre, unrelated, and useless (to you) data.
In C language the last of the string is '\0'.
If you print with the below function, you can see the last character of the string.
scanf("%s", c); add the last character, '\0'.
So, if you use another function, getc, getch .., you should consider adding the laster character by yourself.
#include<stdio.h>
#include<string.h>
int main(){
char c[4+1]; // You should add +1 for the '\0' character.
char *p;
int len;
printf("Enter your name:");
scanf("%s", c);
len = strlen(c);
printf("Your Name is:%s (%d)\n", c, len);
p = c;
do {
printf("%x\n", *(p++));
} while((len--)+1);
return 0;
}
Enter your name:1234
Your Name is:1234 (4)
31
32
33
34
0 --> last character added by scanf("%s);
ffffffae --> garbage
I compiled this code using gcc (tdm-1) 5.1.0 and please tell me why the output doesn't contain "hello"
#include<stdio.h>
void main()
{
int i;
char st[20];
printf("Enter a string ");
scanf("%s",st);
for(i=0;i<20;i++)
{
printf("%c",st[i]);
}
}
Input:hello
Output: # #
You print all 20 elements of the array, but if the user entered a string smaller than that not all elements would be initialized. They would be indeterminate and seemingly random.
Remember that char strings in C are really called null-terminated byte strings. That null-terminated bit is important, and mean you can easily find the end of the string by checking the current character agains '\0' (which is the terminator character).
Or you could just use the strlen function to get the length of the string instead:
for(i=0;i<strlen(st);i++) { ... }
Or use the "%s" format to print the string:
printf("%s", st);
Also note that without any protection the scanf function will allow you give longer input than is space for in the array, so you need to protect agains that, for example by limiting the amount of characters scanf will read:
scanf("%19s",st); // Write at most 19 character (*plus* terminator) to the string
Now for why your input doesn't seem to be printed, it's because the indeterminate contents of the uninitialized elements. While you're not going out of bounds of your array, you still go out of bounds of the actual string. Going out of bounds leads to undefined behavior.
What's probably is happening is that some of the "random" indeterminate contents happens to be a carriage return '\r', which moves the cursor to the start of the line and the output already written will be overwritten by the uninitialized elements in your array.
Here's a short example as Qubit already explained:
#include <stdio.h>
void main () {
char str1[20];
printf("Enter name: ");
scanf("%s", str1);
printf("Entered Name: %s", str1);
}
Here
char st[20];
st is a local variable & default array st contents are garbage not zero. So if you scan less than 20 characters into st, in that case remaining location of array st contains garbage, hence it's printing some junk data like # # in case of
char st[20];
printf("Enter a string ");
scanf("%s",st);
for(i=0;i<20;i++) {
printf("%c",st[i]);
}
& it's a bad practice as if user entered few char lets say 5 char, then your loop rotates 20 times, internally it will do more operations or consume more CPU cycle.
So if you want to print a char array char by char, then you should rotate a loop until \0 char encounters, for e.g
for(i=0;st[i];i++) { /* this fails when \0 encounters */
printf("%c",st[i]);
}
Or
as others suggested you can print char array st using single printf by using %s format specifier like
printf("%s\n",st); /*here printf starts printing from base address of st
and prints until \0 */
Also it's better to initialize char array st while declaring itself. for e.g
char st[20] ="";
Dusting off my C cobwebs here using a site called HackerRank... the challenge here is to read 3 different inputs from stdin and then print out altered data.
Input
The first line contains an integer
The second line contains a double
The third line contains a string / sentence
Output
integer input + variable i
double input + variable d
variable s + string input
Seemed pretty straight forward, I'd use scanf for the integer and double then fgets for the string since scanf would terminate after the first space.
My problem is, doesn't seem like fgets is filling the buffer, but I'm unsure whether or not it could be the sites compiler or just my lack of knowledge.
int i = 4;
double d = 4.0;
char s[] = "HackerRank ";
// Declare second integer, double, and String variables.
int singleNum;
double doubleNum;
char buffer[256];
char outputString[300];
// Read and save an integer, double, and String to your variables.
scanf("%d", &singleNum);
scanf("%lf", &doubleNum);
fgets(buffer, 256, stdin);
// Print the sum of both integer variables on a new line.
singleNum += i;
printf("%d\n", singleNum);
// Print the sum of the double variables on a new line.
doubleNum += d;
printf("%.1f\n", doubleNum);
// Concatenate and print the String variables on a new line
strcat(outputString, s);
strcat(outputString, buffer);
printf("%s", outputString);
// The 's' variable above should be printed first.
However, when I do this, buffer is always empty. If I were to use scanf I would at least get the first word front the string input.
Not super concerned about memory usage here, just trying to complete the problem to work within fixed parameters.
So, my question is - am I doing something wrong here?
My Output:
Input (stdin)
12
4.0
is the best place to learn and practice coding!
Your Output (stdout)
16
8.0
HackerRank
Expected Output
16
8.0
HackerRank is the best place to learn and practice coding!
Compiler Message
Wrong Answer
However, when I do this, buffer is always empty. If I were to use scanf I would at least get the first word front the string input.
The problem is that white space ('\n' entered at the end of scanning double number ) into the buffer is getting consumed
instead consume white space using scanf(" "); before scanning in buffer
scanf(" ");
fgets(buffer, 256, stdin);
Is there a way to include the newline character in the scanf statement so I don't need an extra one?
yes you can further simplify above two statements into :
scanf(" %255[^\n]",buffer); //consumes and scans into buffer
or you could also :
scanf("%lf\n", &doubleNum); //consume at the end
fgets(buffer, 256, stdin); //scan into buffer
One visible problem here is that the outputString is declared, but not initialized:
char outputString[300];
I assume, that it is declared in block scope, so it contains trash values, whatever is on the stack. This may confuse strcat, which expects it to be NUL terminated:
strcat(outputString, s);
The fix would be add following line before the strcat call:
outputString[0] = '\0';
I have solved the Hackerrank C dataType First day challenge problem without using strcat function. Below is the solution to this problem.
int main() {
int i = 4;
double d = 4.0;
char s[] = "HackerRank ";
// Declare second integer, double, and String variables.`enter code here`
int i1=0;
double d1=0.0;
char name[100];
// Read and save an integer, double, and String to your variables.
scanf("%d",&i1);
scanf("%lf",&d1);
getchar(); // Used this function to remove the '\n'from double.
scanf("%[^\n]s",name);
// Print the sum of both integer variables on a new line.
printf("%d\n",i+i1);
// Print the sum of the double variables on a new line.
printf("%0.1lf\n",d+d1);
// Concatenate and print the String variables on a new line
// The 's' variable above should be printed first.
printf("%s%s\n",s,name);
return 0;
}
This is my target:
input: string with mixed ASCII characters (uppercase, lowercase, numbers, spaces)
output: string with only uppercase characters
I have this:
#include <stdio.h>
void csere(char s[]){
int i;
for(i=0; s[i]!='\0'; i++){
if('a'<=s[i] && s[i]<='z'){
s[i]-=32;
}
printf("%c", s[i]);
}
}
void main(){
char s[1];
scanf("%s", &s);
csere(s);
}
My problem is:
The function stops at the first 'space' character in the string.
I tried to change the s[i] != '\0' in the 'for' part for i <
strlen(s) or just for s[i], but I still get the same result.
Example: qwerty --> QWERTY, but qwe rty --> QWE
(smaller problem: The program only accepts strings with length less than 12, if i change the 1 to 0 in main function.)
Thanks for help. Sorry for bad English.
scanf only scans non-whitespace characters with the %s modifier. If you want to read everything on a string you should use fgets with stdin as the third parameter:
fgets(s, sizeof s, stdin);
If you really need to use scanf for homework or something, you should use something like:
scanf("%128[^\n]", s);
Also, take note you are not allocating enough space for the string, the fact that it has not crashed is just pure coincidence... you should allocate the space on your array:
char s[128]; // change 128 for max string size
Actually, the fgets() usage I wrote earlier would only read 1 character (including the terminator string) since you only put 1 character on the array... change the array size and it should work.
You could also just use toupper() on ctype.h, but I guess this is some kind of homework or practice.
Furthermore, if you are allowed to use pointers, this would be a shorter (and probably more performant although that'd have to be tested... compilers are good these days :-) ) way to convert to uppercase (notice though it changes your original char array, and doesn't print it, although that'd be easy to modify/add, I'll leave it to you):
void strupper(char *sptr) {
while (*sptr) {
if ((*sptr >= 'a' ) && (*sptr <= 'z')) *sptr -= 32;
sptr++;
}
}
From scanf
s
Matches a sequence of bytes that are not white-space characters. The application shall ensure that the corresponding argument is a pointer to the initial byte of an array of char, signed char, or unsigned char large enough to accept the sequence and a terminating null character code, which shall be added automatically.
This means, with %s, scanf reads a string until it encounters the first white space character. Therefore, your function converts the given string only to the first space.
To the second (smaller) problem, the array s must be large enough for the entire string given. Otherwise, you overwrite the stack space and get undefined behaviour. If you expect larger strings, you must increase the size of s, e.g.
char s[100];
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
I'm trying to write a C program that counts the number of words and spaces in a given string. Here's what I have so far:
#include <stdio.h>
int main()
{
int i, spaces;
char a[30];
printf("enter the string");
scanf("%s", a);
for(i=0 ; a[0]!="\0" ; i++
{
if (a[i]=' ')
{
spaces++;
}
}
printf("Number of spaces is %d", spaces);
printf("Number of words is %d", spaces + 1);
}
It gives me a weird error at 9:19. Help would be much appreciated.
Updated:
#include <stdio.h>
int main()
{
int i,spaces;
char a[100];
printf("enter the string\n");
scanf("%s",a);
for(i=0 ; a[i]!='\0' ; i++)
{
if (a[i]==' ')
{
spaces++;
}
}
printf("the no. of spaces in the string is %d\n",spaces);
printf("the no. of words in the string is %d\n",spaces+1);
}
Now doesn't metter what string I input, it'll say there's 0 spaces and 1 word. Why is this?
The first think, you forgot the for closing parenthese. And the condition expression you must use '\0' instead of "\0". Also you need to check a[i] not a[0].
for(i = 0; a[i] != '\0'; i++)
{
if (a[i] == ' ')
{
spaces++;
}
}
Note that you should initialize spaces to 0 before using it.
spaces = 0;
Update:
Another thing, to input a full string with spaces use fgets() instead of scanf:
fgets(a, 100, stdin);
The first argument is your string, the second is the maximum number of characters to input and the third is the stream from where you will get the input: stdin in your case wich is the standard input stream.
Live exemple: https://eval.in/101504
In C, a char[] literal is written with double quotes ("), and a char literal is written with single quotes ('). Change "\0" to '\0'. This is the source of your "weird error."
The bracket syntax is syntactic sugar for dereferencing an offset pointer to a contiguous block of memory, based on what you declared it would contain. Maybe a crude diagram could help? This is a depiction of a char[5]. It's a pointer block of memory that can hold 5 chars and a null terminator.
['h']['e']['l']['l']['o']['\0']
^
a // you called your char[] a, so I did too
A char* is a pointer to a char. So you could also call a a char*. Say you wanted to access the first 'l' in the char[]... well, you'd have to point to the address exactly 2*sizeof(char) ahead. a[2] is the same thing as *(a+(2*sizeof(char))).
So when you dereferenced your char* you got a char, obviously. But "\0" is a char[] literal (i.e. a string) and you can't compare the two.
Other problems: you should close the parentheses on your for loop, and make your comparison a[i]!='\0' (that way you are checking each char as you iterate through the char[]. I think you also meant to check if(a[i]==' '). Otherwise you will be clearing out your string with spaces :)
A little tip for going forward: if you are comparing a variable to a literal, put the literal first so you're less likely to make typos like that. e.g. ' '==a[i]. If you used = instead you would get an error (because you'd be trying to assign something to a literal).
Edit: since you updated your code, I'd like to point out that you should probably initialize spaces to be 0.
Now I won't take credit for this, but in case someone in the future is reading, fgets is what you're looking to use instead of scanf. Thanks to drch for pointing this out.
You're always comparing a[0] to '\0' so your loop continues endlessly, compare it to a[i].
One more thing is that "\0" is a string (char*), you need to compare it to '\0' which is a char.
The reason you're getting 0 and 1 is because of the way you're using scanf. Using scanf with %s just reads the first string that does not include white space. So if you typed
"The fox jumped over the moon"
The output will be 0 spaces and 1 word. This is because scanf(%s, a) will just put "The" into a and will ignore the rest of the string.
http://www.cplusplus.com/reference/cstdio/scanf/
You can use scanf("[^\r\n]", a). I believe that should get you what you want (or close to it anyway).