I am trying to input 2 strings in C, and output a 3rd string which the concatenation of string 1 and 2.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
*
*/
int main(int argc, char** argv) {
char stringarray1 [30];
char stringarray2 [30];
char stringarray3 [30];
int length;
printf("Please enter some text less than 30 characters long\n");
scanf("%[a-z, ]", &stringarray1);
printf("Please enter some text less than 30 characters long\n");
scanf("%[a-z, ]", &stringarray2);
strcat(stringarray1, stringarray2);
//length = strlen(stringarray);
printf("The combined string is %s\n", stringarray1);
return (EXIT_SUCCESS);
}
It allows me to input the first string, but then prints the seond and third printf statement, without allowing me to enter the second string.
How can i enter the second string without it exiting? Why does it exit?
Have a look at the documentation of scanf: Your format string "%[a-z, ]" does not what you seem to think what it does. Just use "%s" for strings instead. (It's without any character checks).
You should not put the & for your arrays that are already pointers.
scanf("%[a-z, ]", stringarray2);
At a guess, I'd say you need a \n inside your scanf specification strings. You should probably also be asking for %s instead of %[a-z, ]. The way you have it a single character would match, then when the second scanf is hit, the next character would match.
Also there are some safety issues. You should probably be checking to make sure both strings together aren't larger than 30 chars. As Benoit pointed out, arrays in C also double as pointers to the first character, so you don't use the address-of operator (&) on them when passing them to the C IO routines. That would give the routine the address of your array pointer itself, which the IO routine would then merrily wipe out with character data. Not good!
You know the difference between an chararray a stringarray? I think not. Also you must allocate enough space for you result-string, like:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
*
*/
int main(int argc, char** argv) {
char chararray1 [31];
char chararray2 [16];
char chararray3 [30];
int length;
printf("Please enter some text less than 15 characters long\n");
scanf("%15[a-z, ]", stringarray1);
printf("Please enter some text less than 15 characters long\n");
scanf("%15[a-z, ]", stringarray2);
strcat(stringarray1, stringarray2);
//length = strlen(stringarray);
printf("The combined string is %s\n", stringarray1);
return (EXIT_SUCCESS);
}
I would recommend using fgets instead of scanf, that you can specify a max length (buffer target size - 1) and avoid surprises.
also the target buffer should be twice the size of your input buffers otherwise you risk a memory overwrite
Related
I must write a program in C that can print the middle letter of the string you entered. Spaces () are also calculated, and the number of characters must be odd.
Ex. Input
Hi sussie
--> 9 characters, including space
The output should be s.
I have tried this:
#include <stdio.h>
#include<string.h>
char x[100];
int main(void)
{
printf("Hello World\n");
scanf("%c\n",&x);
long int i = (strlen(x)-1)/2;
printf("the middle letter of the word is %c\n",x[i]);
return 0;
}
and the output always shows the first letter of the word I have entered.
You're only reading the first character from stdin (and incorrectly; you shouldn't be using &).
If you must use scanf, you should use this format:
scanf("%99[^\n]", x);
This is safe and doesn't read past the buffer.
Note that %s wouldn't work here. %s causes scanf to interpret whitespace as the end of the string.
A much better, safer, and easier solution would be to use fgets instead of scanf; fgets is safer and it doesn't require you to change a format string when you change the size of your array:
fgets(x, sizeof(x)-1, stdin);
This eliminates any possible issues with whitespace or buffer overflow.
int main()
{
char arr[1024];
char a;
int i,counter=0;
printf("enter string :: ");
fgets(arr,sizeof(arr),stdin);
for(i=0;i<strlen(arr);i++)
counter++;
for(i=0;i<strlen(arr);i++)
{
if(i==(counter/2))
printf("%c\n",arr[i]);
}
return 0;
}
This question already has answers here:
Why does scanf ask twice for input when there's a newline at the end of the format string?
(7 answers)
Closed 5 years ago.
I am trying to simply get a user input string. The string is saved (scanf) when the person hits enter or the string hits the NULL character. Yet, when I run my program, and type in the string, it continues input until I type \n or \0 (whichever I have in my if statement. Here's my code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MSL 30
char intersperse(char);
char widen_stars(char);
int main(int argc, char *argv[])
{
char *p, *q, *str1[MSL], *str2[MSL];
if(str1[MSL+1] != '\0'){
printf("Please enter a string of maximum 30 characters: ");
scanf("%s\n", str1[MSL]);
}
printf("%s\n", str1[MSL]);
}
This is by no means finished code, i'm just in the process of writing my program when I snagged this annoying bug. The +1 on my MSL is to make sure the NULL character is read so my string doesn't yell at me, idk if it's necessary, but it's a precaution. Thank you answerers.
There are various problems with your code, not just a simple bug. I'll try to describe some of them here.
Turn on compiler warnings. For example, if your array is size 30, there is no element at index 30 (indexes would go from 0 to 29). Your compiler could have warned you about that and other problems.
Store a string in a char array or pointer, but not in a char pointers array. When you wrote:
char *str1[MSL]
You are creating an array of pointers to char, or an array of strings. However, since you're dealing with pointers to char as strings, you'd need to allocate space for them yourself. That's another concept. You probably meant to write an array of char like this:
char str1[MSL]
char *p, *q, str1[MSL], str2[MSL]; /* in your declaration */
Enter at maximum 29 characters. If your string holds 30 char, and you need 1 to mark the null at the end, you've got 29 remaining usable chars. Or… change MSL to 31.
Consider dropping the \n from your scanf format. It will make it read all whitespace (which is what \n represents in a format) waiting for the next non-whitespace. Thus, the input somestring<enter> for example won't be sent directly to your program until the next non-whitespace or EOF.
Give scanf an address. That could be just the array name (which translates to the first element address) or a pointer if you were working with them.
scanf("%s", str1);
scanf("%s", strptr); /* strptr is a char pointer pointing
to previously allocated space */
You can limit the length of what scanf reads. To be safe:
scanf("%29s", str1);
Don't use uninitialised data in comparisons. When you wrote if(str1[MSL+1] != '\0'), what did you expect str1 to contain if you had never stored anything yet?
int
main(int argc, char **argv)
{
char *p, *q, str1[31], str2[31]; /* a lot of unused variables */
printf("Please enter a string of maximum 30 characters: ");
scanf("%30s", str1);
printf("%s\n", str1);
return 0;
}
I am currently trying to solve a problem from CodeChef but I am having troubles with using fgets() inside a loop.
The first input (T) is going to be a positive integer containing the number of user inputs.
Then delimited by newline characters, the user is going to input a string below the length of 10 under any circumstances.
So, I've tried this:
#include <stdio.h>
#include <stdlib.h>
#define SIZE 10
int main()
{
int T;
int diffX, diffY;
char s[SIZE];
scanf("%d", &T);
while (T--){
fgets(s, SIZE, stdin);
printf("%s\n", s);
}
return 0;
}
However, when I attempted to test the code with the following inputs:
3 Hello Hi What
I was only able to input until "Hi" then the program exited successfully (returning 0).
Why is this the case and how can I fix it?
Thank you in advance,
kpark.
fgets() consumes the newline left behind by the first call to scanf(). So, it is consuming 3 lines, but the first line looks like an empty line to the fgets() loop you have.
You can fix this by using fgets() to get the first line too, and parse the string into a number using sscanf().
fgets(s, SIZE, stdin);
sscanf(s, "%d", &T);
/* ... */
It is counting the read of the T as part of the counting. Add a newline in the scanf.
#include <stdio.h>
#include <stdlib.h>
#define SIZE 10
int main()
{
int T;
int diffX, diffY;
char s[SIZE];
scanf("%d\n", &T);
while (T--){
fgets(s, SIZE, stdin);
printf("%s\n", s);
}
return 0;
}
Is your Question is about how to read Multiple Strings in C ?
Then it can be done by 2 ways :-
1.By declaring two dimensional Array of characters.
//Let say we want 6 strings each of them having max 10 characters.
char set[6][10] ;
for(int i=0;i<6;i++)
scanf("%s",set[i])
2.By declaring one dimensional Array of pointers to character (Notice the naming Conventions), in which each of those pointer pointing to a String.
int main(){
int i,numOfStrings;
char temp[30];
printf("Enter Number of strings in set ");
scanf("%d",&numOfStrings);
//Here We have defined array of pointer that will store each string sepratly.
//Arry of pointer to character.
char *setOfStrings[numOfStrings];
for(i=0;i<numOfStrings;i++)
{
printf("Enter string ");
scanf("%s",temp);
setOfStrings[i]= (char*)malloc(sizeof(temp)); //allocted new memory and gave it to array of pointer
strcpy(setOfStrings[i],temp);
}
for(i=0;i<numOfStrings;i++)
{
printf("string = %s \n",setOfStrings[i]);
}
return 0;
}
But that need to understand :
In case of array of pointers we may initialize them with String but Can't take as input from Command line like
char *set[2]={"Dinesh","Kandpal"}; //Its valid but you can't do this from command line
for doing so What we do we will create an space dynamically ,store that address in the one of the element in 1-D array of pointers and then whatever value we have scanned copy that content to the another string to the location that we created using malloc
This is part of an assignment that I'm supposed to submit, this program is supposed to take 2 inputs, a name containing 4 letters and a city containing 5 letters then sub them in that sentence. The problem is that the first word is not being output properly, like if I type john all I get is 'r' instead of the word. I'm new to this and there might be other mistakes, but I wanna fix this one. Help greatly appreciated. :l
#include <stdio.h>
int main(int argc, char **argv)
{
char name1[4];
char city1[5];
printf("\nEnter four letter name:\n");
scanf("%s", name1);
printf("\nEnter five letter city:\n");
scanf("%s", city1);
printf("%s was afraid of the airplane, he walked from %s to Romaine.", name1, city1);
return 0;
}
When I put John and Denver it output "r was afraid of the airplane he walked from Denver to Romaine"
Aham, so this is a buffer overflow. What you should do is:
I. Allocate two reasonably long buffers. 4 and 5 just make me cry. There's a LINE_MAX macro in <limits.h> which may be useful.
II. Use a safe function that lets you specify how big your buffer is. For example, fgets() is an excellent function for inputting a line of text. Using it also has the benefit that it really always reads an entire line (if the buffer passed to it is large enough). scanf() requires some messing with the %s conversion specifier before you can make it accept whitespace and stuff.
char name[LINE_MAX];
char city[LINE_MAX];
fgets(name, sizeof name, stdin);
fgets(city, sizeof city, stdin);
#include <stdio.h>
int main(int argc, char **argv)
{
char name1[8];
char city1[8];
printf("\nEnter four letter name:\n");
scanf("%s", name1);
printf("\nEnter five letter city:\n");
scanf("%s", city1);
printf("%s was afraid of the airplane, he walked from %s to Romaine.", name1, city1);
return 0;
}
The solution: Make sure the character arrays are large enough for the input.
scanf is an unsafe function as it will fetch data from its input stream and copy it past the end of the buffer you provide if it's not large enough. In addition it will place a nul terminating character at the end of the copied string.
In your example John requires at least 5 characters while Denver at least 7 because you must account for the terminating character.
You should consider using a larger buffer for both strings, or as a better alternative, write your own function which uses a buffer to store the string and then copies it to the final destination buffer (assuming length is enough, truncating otherwise).
Take a look at this answer: How to prevent scanf causing a buffer overflow in C?, there are some common work arounds for your problem.
I'm trying to ask the user to type in a string so I will print the length of the string. My code is built succeeded. However, when I entered a word and pressed 'enter', the program keeps running. I had to enter a second word, then the length of the first string displays. I'm confused at argv[1]. Can someone give me some tips and hint on how to fix this? Thanks in advance for your time.
Please note that I'm not allowed to use any string function.
int main(int argc, char* argv[]){
char* s=argv[1];
char input[256];
s = input;
printf("Please enter a string: ");
scanf("%s\n", s);
int str_length = 0;
while (s[str_length] != '\0')
{
str_length++;
if (s[str_length] == '\0') break;
}
printf("%d\n", str_length);
return 0;
}
argv[] is the array that holds your command line parameters, argv[1] is the first one (other than the command representation itself in argv[0], of course). You assign it to s then immediately overwrite s, so it's not really needed here.
The reason you're having to enter two lines is the \n at the end of your input format. It requires whatever can match the format string followed by a newline, hence the %s\n is eating your first newline so that scanf has to go back for another one.
%s on it's own will fix that problem but introduce another one if what you're after is a full line of input - it will only read up to the first whitespace. For a proper line input function, see here.
It does full line input with protection against buffer overflows and detection/cleanup of lines that were too long, something sorely missing in the scanf("%s") input method.
In addition, the if statement within the while is superfluous here since the while itself will catch the end of the string, and it makes little sense to have both input and s refer to the same array (it would make sense if you changed s at some point, but that's not happening here).
So, a variant without the advanced line iput function could be as simple as:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, char* argv[]) {
char input[256];
int str_length = 0;
printf ("Please enter a string: ");
scanf ("%s", input);
while (input[str_length] != '\0') /* Or consider using strlen() */
str_length++;
printf ("%d\n", str_length);
return 0;
}
If you enter Hello, you'll see that it prints out 5 immediately. You'll also see 5 if you enter Hello Pax, which is one reason to choose the advanced input function (the other, very important, reason is to avoid introducing a buffer overflow vulnerability into your program).
argv is used to pass process arguments. this means you can run your program like
a.out 123 abcd
argv[1] will already be assigned to a value of 123. you do not have to read it as you are doing now. in your current code , you are overwriting the reference of s to a new string after assigning it with argv[1].
This is what you want
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define MAX 100
int main(int argc, char* argv[]){
char tmp[MAX];
printf("Plese enter a string:\n");
scanf("%s", tmp);
printf("the length is %d\n", strlen(tmp));
return 0;
}
The argv and argc is another thing like this:
argv[0] = a.exe
argv[1] = 12345
int main(int argc, char* argv[]){
printf("the length is %d\n", strlen(argv[1]));
return 0;
}
/*-------------------- Output --------------------
> a.out 12345
the length is 5
------------------------------------------------*/
Just change the scanf line:
scanf("%s", s);
As you have it (scanf("%s\n", s);), it requires a sequnce of characters ending in \n, then another \n to indicate when the input is finished.