Why does it print out the new word minus the first character when i printf("%s\n",array[0]) and not "Hello". Any tips for how to do solve that ?
Thanks in advance !
#include <stdio.h>
#include <string.h>
int main()
{
char newword;
char array[100][20]={
{'H','e','l','l','o'},
{'W','o','r','l','d'},
};
printf("%s\n",array[0]);
printf("%s\n",array[1]);
printf("Type a new word: ");
scanf("%s",&newword);
strcpy(array[1],&newword);
printf("%s\n",array[0]);
printf("%s\n",array[1]);
return 0;
}
Of course newword is not capable of holding a string (except the empty string) since it's just a single character, not an array. Using that with scanf() like you do is undefined behavior.
Make it:
char newword[20];
for instance, and preferably also scanf(" %19s", newword);, and check that scanf() succeeded.
Your code char newword; ... scanf("%s",&newword) yields undefined behaviour; you read in a string into a variable holding a single character; From that point on, all bets are off.
Write char newword[100]; ... and things should do better.
Related
Problem Statement
Today is Newton School's first class of this year. Nutan, a student at
Newton School, has received his first assignment. He will be given a
string as input. His task is to print "Gravity'' if the input is
"Apple''; otherwise, he will have to print "Space''.
Can you help Nutan in solving his first assignment? Note that the
quotation marks are just for clarity. They are not part of the input
string, and should not be a part of your output string. Input The
input consists of a single line that contains a string S (1 ≤ length
of S ≤ 10). The string only consists of lowercase and uppercase
letters. Output Print "Gravity'' or "Space'' according to the input.
What I am trying to do:
Basically, I am taking a user-defined string and trying to compare it with the hard input string i.e "Apple". If both the string matches then it will print "Gravity" or else it will print "Space"
#include <stdio.h> // header file for Standard Input Output
#include <stdlib.h> // header file for Standard Library
#include <string.h> // for strcmp() function
int main() {
char str1[10]="Apple";
char str2[20];
int value;
printf("Enter the input ");
scanf("%s", &str2[20]);
value = strcmp(str1, str2);
if(value==0)
printf("Gravity");
else
printf("Space");
return 0;
}
scanf("%s", &str2[20]);
may invoke undefined behavior by out-of-range access. You should:
Pass the pointer to the first element of the array, not one to the next element of the last element. (most) arrays in expressions are automatically converted to pointes to their first elements.
Specify the maximum length to read to avoid buffer overrun.
Check if reading succeeded.
The line should be:
if (scanf("%19s", str2) != 1) {
puts("read error");
return 1;
}
Some improvements:
Don't use "%s", use "%<WIDTH>s", to avoid buffer-overflow
Instead of using bare return 0;, use return EXIT_SUCCESS;, which is defined in the header file stdlib.h.
always check whether scanf() input was successful or not
Use const char * instead of char str1[10]
There's no need for int value;
SYNTAX ERROR: &str2[20]
There's no need for passing the address of str2 READ MORE
Initialize str2 with zeroes
Add 1 more space in your str2 for NULL ('\0') terminating character
Final Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
const char *str1 = "Apple";
char str2[21] = {};
printf("Enter the input ");
if(scanf("%20s", str2) != 1)
{
fprintf(stderr, "bad input\n");
return EXIT_FAILURE;
}
if(strcmp(str1, str2) == 0)
printf("Gravity");
else
printf("Space");
return EXIT_SUCCESS;
}
You are entering a string starting from the memory address after the last element of the array str2
scanf("%s", &str2[20]);
and then trying to compare the character array str1 with the non-initialized array str2
value = strcmp(str1, str2);
Change the call of scanf like
scanf("%19s", str2);
And the program will be safer if at least the array str2 will be initially initialized
char str2[20] = "";
Also as the array str1 is not changed then instead of the array you could declare a pointer to the string literal like
const char *str1 = "Apple";
And instead of the calls of printf
printf("Gravity");
//..
printf("Space");
it is better to use calls of puts
puts("Gravity");
//..
puts("Space");
Pay attention to that neither declaration from the header <stdlib.h> is used in your program. So you may remove this include directive
#include <stdlib.h> // header file for Standard Library
I have a char pointer: char *sentences; and I read it like this:
#include <stdio.h>
int main() {
char *sentences;
sentences="We test coders. Give us a try?";
printf("%s", sentences);
return 0;
}
but I want to read with scanf() function in c.
scanf("%[^\n]s",S); or scanf("%s",S); didn't work.
How can I do that?
Are you declaring the variable char *sentences; and immediately trying to write to it with scanf? That's not going to work.
Unless a char * pointer is pointing to an existing string, or to memory allocated with malloc-family functions, assigning to it with scanf or similar is undefined behavior:
char *sentences;
scanf("%s", sentences); // sentences is a dangling pointer - UB
Since you haven't actually shared your code that uses scanf and doesn't work, I can only assume that's the problem.
If you want to assign a user-supplied value to a string, what you can do is declare it as an array of fixed length and then read it with a suitable input function. scanf will work if used correctly, but fgets is simpler:
char sentence[200];
fgets(sentence, 200, stdin);
// (User inputs "We test coders. Give us a try")
printf("%s", sentence);
// Output: We test coders. Give us a try.
Also, never, ever use gets.
I expected to get errors in following code, but I did not. I did not use & sign. Also I am editing array of chars.
#include <stdio.h>
int main()
{
char name[10] ="yasser";
printf("%s\n",name);
// there is no error ,
// trying to edit array of chars,
// also did not use & sign.
scanf("%s",name);
// did not use strcpy function also.
printf("%s\n",name);
return 0;
}
I expected to get errors in following code, but I did not.I did not use & sign.
scanf("%s",name);
That's totally ok as name is already the address of the character array.
It sounds like you have several questions:
calling scanf("%s", name) should have given an error, since %s expects a pointer and name is an array? But as others have explained, when you use an array in an expression like this, what you always get (automatically) is a pointer to the array's first element, just as if you had written scanf("%s", &name[0]).
Having scanf write into name should have given an error, since name was initialized with a string constant? Well, that's how it was initialized, but name really is an array, so you're free to write to it (as long as you don't write more than 10 characters into it, of course). See more on this below.
Characters got copied around, even though you didn't call strcpy? No real surprise, there. Again, scanf just wrote into your array.
Let's take a slightly closer look at what you did write, and what you didn't write.
When you declare and initialize an array of char, it's completely different than when you declare and initialize a pointer to char. When you wrote
char name[10] = "yasser";
what the compiler did for you was sort of as if you had written
char name[10];
strcpy(name, "yasser");
That is, the compiler arranges to initialize the contents of the array with the characters from the string constant, but what you get is an ordinary, writable array (not an unwritable, constant string constant).
If, on the other hand, you had written
char *namep = "yasser";
scanf("%s", namep);
you would have gotten the problems you expected. In this case, namep is a pointer, not an array. It's initialized to point to the string constant "yasser", which is not writable. When scanf tried to write to this memory, you probably would have gotten an error.
When you pass arrays to functions in C, they decay to pointers to the first item.
Therefore for:
char name[] ="yasser";
scanf("%s", name) is the same as scanf("%s", &name[0]) and either of those invocations should send shivers down your spine, because unless you control what's on your stdin (which you usually don't), you're reading a potentially very long string into a limited buffer, which is a segmentation fault waiting to happen (or worse, undefined behavior).
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv, char **envp) {
char *myName = (char *) calloc(10, sizeof(char));
*(myName)='K'; *(myName+1)='h'; *(myName+2)='a'; *(myName+3)='l'; *(myName+4)='i'; *(myName+5)='d';
printf("%s\n",myName);
scanf("%s",myName);
printf("%s\n",myName);
return (EXIT_SUCCESS);
}
#include <stdio.h>
#include <string.h>
int main()//fonction principale
{
char name[10] ="yasser";
int longeur=0;
printf("%s\n",name);
scanf("%s",name);
longeur = strlen(name);
for (int i=0;i<longeur;i++) {
printf("%c",*(name+i));
}
return 0;}
I'm new to C and i would like to learn something that is troubling me.
I have a code where i used strtok and basically it gets a string with the _#_ and seperates it from the string leaving the rest into chars and ints(i used atoi for that)
The program runs fine when i enter something like that: hello_#_2001_#_name_#_HARRY it gives me back hello,2001,name and HARRY. But when I input only hello_#_ it continues to run though stops doing anything. I think i need to assign a certain pointer to the first NULL but not sure if what i think is correct could you please help?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *split(char words[99])
{
int i;
char *word=strtok(words, "_#_");
char *year=strtok(NULL, "_#_");; // assigning NULL for previousely where it left off
char *definition=strtok(NULL,"_#_");
char *synonyms=strtok(NULL,"_#_");
i=atoi(year);
printf("%s\n", word);
printf("%i\n",i);
printf("%s\n", definition);
printf("%s\n", synonyms);
return 0;
}
int main()
{
char words[100];
printf("Enter a string\n");
scanf("%s", words);
split(words);
}
When I run your program and enter the string hello_#_, it throws a segfault when atoi is called. This is expected since year, definition, and synonyms will all be NULL. So you should check year for a NULL value before calling atoi.
From the man page:
The strtok() and strtok_r() functions return a pointer to the beginning of each subsequent token in the string, after replacing the token itself with a NUL character. When no more tokens remain, a null pointer is returned.
Try checking if the return value of strtok() is NULL before continuing.
You need to do some error checking. If you run out of tokens, strtok returns NULL, and then if you try to actually do something with that non-existing string (like pass it to atoi or try to print it) Bad Things will happen. It's up to you to decide what your function should do in that case (abort? Print what it can?) but you'll have to do something.
I'm creating a char* which essentially will be treated as an string. The string is suppose to be used over and over again. Everytime I'm attempting to check with the while loop and see if its correct to the "quit"...
*I keep getting a segmentation fault...What am I doing wrong -- Pretty idiotic mistake - possibly?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char* argv[])
{
char* input = (char*)malloc(sizeof(char));
input = "CONTINUE";
while(strcmp(input, "quit") != 0)
{
printf("%s", "System: ");
scanf("%s", input);
}
return 0;
}
Two problems I see in first look:
char* input = (char*)malloc(sizeof(char));
You are assigning your pointer a memory of just one character. It should have enough memory to hold your string not just one character.
You should copy the string in to the allocated buffer using strcpy. Not aassign a string literal to your pointer. Note that modifying such a string literal results in Undefined Behavior.
input = "CONTINUE";
Correct way of doing the above 2 are:
char* input = (char*)malloc(sizeof(MAX_LENGTH));
strcpy(input, "YOURSTRING");
Where MAX_LENGTH is sufficient to hold your input strings.
You are trying to change a literal which is illegal.
Try:
char* input = (char*)malloc(sizeof(char)); /* You need more than one char. */
char* input = (char*)malloc(LENGTH); /* Allocate `LENGTH` chars. */
input = "CONTINUE"; /* You can't write (scanf) over a string literal. */
strcpy(input, "CONTINUE"); /* Now it's legal to write over `input`. */
Other points to watch out for:
Using scanf with a bare "%s" is unsafe. You should use something like "%10s" to make sure a potentially malicious user doesn't enter more than 10 characters
Did you know sizeof(char) isn't needed since it's guaranteed to be 1 ?