how to scan strings with white spaces and print them C - c

I have to read a string, to concatenate with another and print the result
I tried this code:
int main(){
char s= "StackOverflow ";
char ss[100];
fgets(ss,100,stdin);
// i know i can use strcat but i don't want it here
printf("%s%s",s,ss);
return 0;
}
the ss is "is the best site for learning things!"
Some help?

First of all, you have to make your program compilable, as compilation gives some errors.
1.) s must be defined as char *s or char s[] because char s only allows one character to be stored there, and not an array. char *s declares a pointer to the string literal and char s[] declares an array of characters of as many as present in the string literal and initializes it with the characters of the specified string literal.
2.) stdin is a global variable of type FILE * (actually it isn't but it behaves as) that represent the standard input. If you don't declare it, the compiler doesn't know where the stdin identifier came from, so it issues an error. The way to eliminate this second error is to #include <stdio.h> which has a definition for it and makes the compiler happy.
Once you do these two steps, your program is:
#include <stdio.h>
int main(){
char s[]= "StackOverflow ";
char ss[100];
fgets(ss,100,stdin);
// i know i can use strcat but i don't want it here
printf("%s%s",s,ss);
return 0;
}
and behaves as you wanted.

Related

C String Length using null

I know the C language has dynamic length strings whereby it uses the special character null (represented as 0) to terminate a string - rather than maintaining the length.
I have this simple C code that creates a string with the null character in the fifth index:
#include <stdio.h>
#include <stdlib.h>
int main () {
char * s= "sdfsd\0sfdfsd";
printf("%s",s);
s[5]='3';
printf("%s",s);
return 0;
}
Thus, a print of the string will only output up to the fifth index. Then the code changes the character at the fifth index to a '3'. Given my understanding, I assumed it would print the full string with the 3 instead of the null, as such:
sdfsdsdfsd3sfdfsd
but instead it outputs:
sdfsdsdfsd
Can someone explain this?
This program exhibits undefined behavior because you modify a read-only string literal. char* s = "..." makes s point to constant memory; C++ actually disallows pointing non-const char* to string literals, but in C it's still possible, and we have to be careful (see this SO answer for more details and a C99 standards quote)
Change the assignment line to:
char s[] = "sdfsd\0sfdfsd";
Which creates an array on the stack and copies the string to it, as an initializer. In this case modifying s[5] is valid and you get the result you expect.
String literals can not be changed because the compiler put the string literals into a read-only data-section (but this might vary by underlying platform). The effect of attempting to modify a string literal is undefined.
In your code:
char * s= "sdfsd\0sfdfsd"
Here, s is char pointer pointing to a string "sdfsd\0sfdfsd" stored in read-only memory, making it immutable.
Here you are trying to modify the content of read-only memory:
s[5]='3';
which leads to undefined behavior.
Instead, you can use char[]:
#include <stdio.h>
int main () {
char a[] = "sdfsd\0sfdfsd";
char * s = a;
printf("%s",s);
s[5]='3';
printf("%s\n",s);
return 0;
}
This operation has failed:
s[5] = 3;
You're trying to change a string literal, which is always read-only. My testing shows the program exited with segfault:
Segmentation fault (core dumped)
You should store it in an array (or allocated memory) before any attempts to change it:
char s[] = "sdfsd\0sfdfsd";
With the above change, the program works as intended.
#include <stdio.h>
int main(){
char x[10] = "aa\0a";
x[2] = '1';
puts(x);
printf("\n\n\nPress any key to exit...");
getch();
return 0;
}
Output: aa1a

Char arrays and scanf function in C

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;}

Error in initializing array in C

Below is my code:
#include <stdio.h>
#include <stdlib.h>
typedef int index_key;
typedef char text_t;
text_t *create_text()
{
//text_t text[SIZ];
text_t *c;
text_t text[]="fl";
c= text;
return c;
}
int main()
{
text_t * create();
return 0;
}
I get an error - expected expression before ‘]’ token. Why is this error occuring? Isn't text[] a global declaration and I can access it anywhere? What is wrong in this program and how should I correct it.
You cannot have an array definition like
text_t text[];
Either specify the size,
#define SIZ 256 //arbitary value
text_t text[SIZ];
or use initializer.
text_t text[] = {`A`, `B`, `C`};
EDIT:
As per the latest addition, please be informed that "sldk" (as you've iused) and {'s', 'd', 'l', 'k'} (as i've suggested) are not the same. The former is a string literal while the later being initalizer list of chars. You can use the second in your case, not the first one.
EDIT 2
That said, your create_text() function is wrong. Effectively, you're returning the address of a local variable text. Incorrect. Will invoke UB.
I see the following problems:
text_t text[];
is a declaration, not a definition. You have to add a line that defines text, such as:
text_t text[100];
The line
text[]="sldk";
is wrong on two accounts.
You cannot assign to an array using the = operator.
You cannot use text[] to access the array.
Here's a fixed version of your program.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef int index_key;
typedef char text_t;
// This is a forward declaration of the array.
text_t text[];
text_t *create()
{
text_t *c;
// One way to get some string into a char array.
strcpy(text,"sldk");
c = text;
return c;
}
// This is the definition of the array.
text_t text[100];
int main()
{
text_t * create();
return 0;
}
Update
Regarding your updated create_text function...
It should work since string literals are stored in read-only memory of the program. It will lead to problems as soon as you try to change anything in it. It's better to use a safer approach, such as:
text_t *create_text()
{
text_t *c = malloc(20);
strcpy(c, "fl");
return c;
}
The C language does not have a built in string data type unlike C++, Java or C#.
The strings are represented as arrays of characters in C. So any array in C should have some size.
int numbers[10];
char string[50];
The C function which operate on these types of strings ( like strlen which calculates the length of the strings expects a 'null' or '\0' character at the end of the array.
Initializing a character array with string literal like "test" will automatically insert a null character at the end.
char str[10] = "test";
characters stored {'t','e','s','t','\0'}
If you are initializing it with comma separated characters, you need to explicitly specify this character.
char str[10] = {'t','e','s','t', '\0'}; //explicit null character
So, generally the array size is one more than the maximum size of the string you want to store. So it is quite common to see declaration like the following.
char name[MAXLEN+1];
If you are using C++, you can use a build-in data type called string.
string str;
Hope this helps

Write string into initialised blank char array [duplicate]

This question already has answers here:
Assigning char array a value in C
(2 answers)
Closed 8 years ago.
i have just started learning C and i am confused on how to write a string into a simple char array in C. i understand that C does not have a string data type, and i read that most websites declare string in one of this way
char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
char greeting[] = "Hello";
however what if i have initialized a char array of
char greeting[50];
and i try to give it a string value.
char greeting[50];
greeting = "Zack";
i am given a error, why?
strcpy is designed to copy "strings".
Use as follows:
char greeting[50];
strcpy(greeting, "Zack");
Be aware of potential overruns if the destination isn't big enough.
Use standard function strcpy declared in header <string.h> that to copy a string in a character array
#include <string.h>
//...
char greeting[50];
strcpy( greeting, "Zack" );
There are other functions declared in header <string.h> that also can be used to copy strings in character arrays. For example
memcpy
strncpy
strcat
strncat
An example of using strcat instead of strcpy
#include <string.h>
//...
char greeting[50];
greeting[0] = '\0';
strcat( greeting, "Zack" );
Arrays have no the assignment operator. So the compiler issues an error for this code snippet
char greeting[50];
greeting = "Zack";
But there is a trick when you may assign character arrays. To do that you need to enclose a character array in a structure and use a compound literal. For example. Contrary to arrays structures have the assignment operator that performs member-wise copy of structure.
#include <stdio.h>
#include <string.h>
int main(void)
{
struct A { char greeting[50]; } s;
s = ( struct A) { "Zack" };
puts( s.greeting );
return 0;
}
The output will be
Zack
That this code would be compiled you need a compiler that supports C99.
You use strcpy():
char greeting[50];
strcpy(greeting, "Zack");
This will copy the four characters and the terminating zero into greeting.
Beware that it knows nothing about the available space at greeting, so it's perfectly possible to do the wrong thing.
You're getting an error because you're basically trying to assign a string constant to an array. The array greeting decays to a pointer, but it's a char *const pointer.
You need to use strcpy to copy the literal.
In C, the folowing code will print "foo":
char greeting[50];
if(greeting == &greeting[0]){
printf("foo");
}
else{
printf("bar");
}
This happens because the variable of the array (greeting) contains a pointer to the first element of it (greeting[0]).
So, if you asign:
greeting = "Zack";
You are saying: Let greeting have the address of where the literal string "Zack" is in the memory.
As changing the address of a array is not allowed, you get an error.

strcat in C error segmentation

#include <stdio.h>
#include <string.h>
int main() {
char tab[2]={"12"};
FILE *outfile;
char *outname = "/home/dir/";
printf("%s", strcat(outname,tab));
outfile = fopen(strcat(outname,btab), "w");
if (!outfile) {
printf("There was a problem opening %s for writing\n", outname);
}
}
I have this error: Segmentation Fault.
How can I fix it?
At least two errors:
char tab[2] = {"12"};
You'd better use tab[3] or even better tab[] -- you need one extra char for the terminating NUL character.
Also,
char *outname = "etc...";
creates a constant string in the data segment of the executable -- it can't be overwritten, since strcat is using its first parameter to concatenate the two strings. So when strcat() tries to do so, it segfaults. Use
char outname[50]; // something big enough
strcpy(outname, "/home/dir");
instead.
outname is a string literal and string literals are not modifiable. Modifying a string literal is undefined behavior.
outname is Const pointer so once you have entered some thing in it, you can't modify it.
However if you want to copy things in it, make a char array of the size equal to tab[] array because here the size of string to be copied is known. Most of the time char pointers like OUTNAME are used when you are taking input from a user once and you don't know how long that input will be.
In your code,
char *outname = "/home/dir/";
outname is a string literal and hence when used with strcat, it does not have enough length to hold the concatenated string.This results in segmentation fault.
Same is the case had you declared it as below,
char outname[] = "/home/dir/";
The solution for this to declare the size of the outname big enough to hold the concatenated string.
char outname[80] = "/home/dir/";

Resources