Incorrect output, simple strings exercise - C - c

I am trying to write a function that gets a string of letters, either capital letters or small letters, and prints 2 other strings, one with only the capitals, and one only with the small letters. for example:
input: AaBbCcDD
Output: Capital string is ABCDD, non capital is abc
My code is not working correctly, it seems to skip over the last letter. To test it, I wrote the following code:
int length;
printf("Please enter length of string\n");
scanf("%d",&length);
string=create_string(length);
scan_string(string,length);
printf("The string entered is: \n");
print_string(string,length);
Where create_string is:
char* create_string(int size)
{
char* string;
string=(char*)malloc(size*sizeof(char));
return string;
}
Scan string is:
void scan_string(char* string, int size)
{
int i;
printf("Please enter %d characters\n",size);
for(i=0;i<size;i++)
scanf("%c",string+i);
}
And print string is
void print_string(char* string,int size)
{
int i;
for(i=0;i<size;i++)
printf("%c ",*(string+i));
}
When I try even just to print the string I entered, this is what I get, after I input aaAAB
The output is a a A A.
it skipped over the B.

The problem is with the scanf that reads characters using %c: it follows the scanf that reads the length using %d, which leaves an extra '\n' character in the buffer before the first character that you get.
If you modify the output to put quotes around your characters, you would actually see the \n:
void print_string(char* string,int size)
{
int i;
for(i=0;i<size;i++)
printf("'%c' ",*(string+i));
}
This prints
'
' 'a' 'a' 'A' 'A'
(demo on ideone)

You can change your first scanf to read '\n' as below. This will read the extra '\n'
scanf("%d\n", &length);

I think your code is unnecessarily elaborated. To read a string the function fget() with parameter stdin is a simpler choice.
For example, I wuold not ask to the user for the length of the string.
Perhaps it is better to use a buffer with fixed length, and to restrit the user to enter a string with the length less than which you have been previously stipulated.
#define MAXLEN 1000
char buffer[MAXLEN] = "";
fgets(buffer, MAXLEN, stdin);
If the user attempts to enter a string with more than MAXLEN characters, it would be necessary to handle the end-of-line in some way, but I think this is out of topic.
So, in general, let us suppose that MAXLEN is large enough such that buffer contains the \n mark.
Now, a call to your function print_string() can be done.
However, it would be better to do this:
printf("%s", buffer);
I think that you probably need to take in account the C convention for strings: a string is a char array whose last element is marked with the character '\0' (null character, having always code 0).
Even if you want to insist in your approach, I think that scanf() is a bad choice to read individual characters. it is more easy to use getchar(), instead.
By using scanf() you have to broke your brain figurating out all the stuff around the behaviour of scanf(), or how to handle the read of characters, and so on.
However, getchar() reads one char at a time, and that's (almost) all. (Actually, the console commonly not returns the control to the user until an end-of-line \n has been read).
string[i] = getchar();

The problem is because the scanf does not eat the "\n". Hence there is still one '\n' remaining at your first input. This will be counted at the next scanf.
Try to put an additional getchar() right after your first scanf.
printf("Please enter length of string\n");
scanf("%d",&length);
getchar(); // remove '\n'
string=create_string(length);

Related

Output didn't include all of the characters

I was trying to input a string of characters and only output the last and the first character respectively. Below is the code I'm using.
#include<stdio.h>
int main(){
for(int i=0;i<3;i++){
int n; // length of the string
char string[101];
scanf("%d %s", &n, &string);
fflush(stdin); // sometimes I also use getchar();
printf("%c%c", string[n+1], string[0]);
}
printf("\n");
return 0;
}
I'm using for loop because i wanted to input the string 3 times, but when I ran the code the input isn't what I expected. If I input e.g.
5 abcde
output
a //there's space before the a
can you help me tell where I've gone wrong?
input:
5 abcde
6 qwerty
3 ijk
excpeted output:
ea
yq
ki
Few problems in your code:
In this statement
scanf("%d %s", &n, &string);
you don't need to give & operator with string. An array name, when used in an expression, converts to pointer to first element (there are few exceptions to this rule). Also, the size of string array is 101 characters but if you provide input more than 101 characters, the scanf() end up accessing string array beyond its size. You should restrict the scanf() to not to read more than 100 characters in string array when input size is more than that. (keep the remain one character space is for null terminating character that scanf() adds). For this, you can provide width modifier in the format specifier - %100s.
You are not validating the string length input against the input string from user. What happen, if the input string length is greater than or less than the actual length of input string!
fflush(stdin) is undefined behaviour because, as per standard, fflush can only be used with output streams.
I was trying to input a string of characters and only output the last and the first character respectively.
For this, you don't need to take the length of the string as input from user. Use standard library function - strlen(). This will also prevent your program from the problems that can occur due to erroneous length input from user, if that is not validated properly.
Putting these altogether, you can do:
#include <stdio.h>
#include <string.h>
int main (void) {
for (int i = 0; i < 3 ; i++) {
char string[101];
printf ("Enter string:\n");
scanf("%100s", string);
printf("Last character: %c, First character: %c\n", string[strlen(string) - 1], string[0]);
int c;
/*discard the extra characters, if any*/
/*For e.g. if user input is very long this will discard the input beyond 100 characters */
while((c = getchar()) != '\n' && c != EOF)
/* discard the character */;
}
return 0;
}
Note that, scanf(%<width>s, ......) reads up to width or until the first whitespace character, whichever appears first. If you want to include the spaces in input, you can use the appropriate conversion specifier in scanf() or a better alternative is to use fgets() for input from user.
Line 11: string[n+1] -> string[n-1]

Counting the Whole String Including The Spaces in C

I'm trying to set up a code that counts the whole string and doesn't stop after the first space that it finds. How do I do that?
I tried this kind of code but it just counts the first word then goes to display the number of letters in that first word.
So far this is what I have tried.
int main(){
char get[100];
int i, space=0, len=0, tot;
scanf("%s", get);
for (i=0; get[i]!='\0'; i++)
{
if (get[i] == ' ')
space++;
else
len++;
}
tot = space + len;
printf("%i", tot);
}
And
int main(){
char get[100];
int len;
scanf("%s", &get);
len = strlen(get);
printf("%i", len);
}
But would still get the same answer as the first one.
I expected that if the
input: The fox is gorgeous.
output: 19
But all I get is
input: The fox is gorgeous.
output: 3
strlen already includes spaces, since it counts the length of the string up to the terminating NUL character (zero, '\0').
Your problem is that that the %s conversion of scanf stops reading when it encounters whitespace, so your string never included it in the first place (you can verify this easily by printing out the string). (You could fix it by using different scanf conversions, but in general it's easier to get things right by reading with fgets – it also forces you to specify the buffer size, fixing the potential buffer overflow in your current code.)
The Answer by Arkku is correct in its diagnose.
However, if you wish to use scanf, you could do this:
scanf("%99[^\n]", get);
The 99 tells scanf not to read more than 99 characters, so your get buffer won't overflow. The [^\n] tells scanf to read any character until it encounters the newline character (when you hit enter).
As Chux pointed out, the code still has 2 issues.
When using scanf, it is always a good idea to check its return value, which is the number of items it could read. Also, indeed the \n remains in the input buffer when using the above syntax. So, you could do this:
if(scanf("%99[^\n]", get) == 0){
get[0] = 0; //Put in a NUL terminator if scanf read nothing
}
getchar(); //Remove the newline character from the input buffer
I will take one example to explain the concept.
main()
{
char s[20], i;
scanf("%[^\n]", &s);
while(s[i] != '\0') {
i++;
}
printf("%d", i);
return 0;
}
i have used c language and u can loop through the ending the part of the string and you will get the length. here i have used "EDIT SET CONVESRION METHOD" to read string, you can also gets to read.

How to get inputs accepted in this program?

I can't take inputs except string.
If I give inputs in code itself, program is working.
But when I try to take inputs, its not working.
How do I get it to accept given inputs?
For example, if s were "codebook", and from == 'o' and to == 'e', s would become "cedebeek".
#include<stdio.h>
#define MAX 50
void replace(char *s, char from, char to)
{
int i=0;
while(s[i]!='\0')
{
if(s[i]==from)
{
s[i]=to;
}
i++;
}
}
int main()
{
char str[MAX];
char from;
char to;
printf("Enter the string");
scanf("%[^\n]s",&str[0]);
printf("\nEnter the character to be replaced");
scanf("%c",&from);
printf("\nEnter the character to be replaced with");
scanf("%c",&to);
replace(str, from, to);
printf("\nThe modified string is %s",str);
return(0);
}
There are a couple of problems in the posted code. Since arrays decay to pointers to their first elements in most expressions, there is no need for the address operator & in the call to scanf(); also, the trailing s is not part of the scanset conversion specifier:
scanf("%[^\n]", str);
As pointed out by #M.M in the comments, it is not incorrect to use &str[0] here instead of str, but it is more idiomatic, and I personally find it more clear, to use the less cluttered str.
When scanf() returns, a newline character will be left in the input stream, so you should add a leading space in the next call to scanf() to skip over this \n character before reading the user input:
scanf(" %c",&from);
And this call to scanf() will also leave a \n character in the input stream, so again:
scanf(" %c",&to);
Note that you should really specify a maximum width to avoid buffer overflow when reading user input into a string; there is no easy way to do this with MAX, but you can do:
scanf("%49[^\n]", str);
You could further improve code and ensure that input is as expected by checking the values returned by the calls to scanf().

C string compare wont allow space bar

using the cprogrammingsimplified tutorial for writing my own stringcompare.
Finished reformatting it and ran it.
works fine for single words,
But
typing space bar skips the second scan and immediately outputs
'words aren't the same'
anyone any idea how to allow the use of even a single space bar?
Thanks in advance.
#include <stdio.h>
int mystrcmp(char s1[], char s2[]);
int main(){
char s1[10], s2[10];
int flag;
printf("Type a string of 10\n\n");
scanf("%s",&s1);
printf("type another string of 10 to compare\n\n");
scanf("%s",&s2);
flag = mystrcmp(s1,s2);
if(flag==0)
printf("the words are the same\n\n");
else
printf("the words are not the same\n\n");
return 0;
}
int mystrcmp(char s1[], char s2[]){
int l=0;
while (s1[l] == s2[l]) {
if (s1[l] == '\0' || s2[l] == '\0')
break;
l++;
}
if (s1[l] == '\0' && s2[l] == '\0')
return 0;
else
return -1;
}
Use fgets() to read full lines, rather than scanf() to read space-separated words.
Remember that fgets() will include the linefeed in the string, though.
It is not strcmp that wouldn't allow space bar, it's scanf with %s format specifier. The input is truncated at the space, so the second string that you read is actually the continuation of the first string.
You can fix this by using %9[^\n] instead of %s in your format specifier:
printf("Type a string of 10\n\n");
scanf("%9[^\n]",s1); //s1 is char [10]
printf("type another string of 10 to compare\n\n");
scanf("%9[^\n]",s2); //s2 is char [10]
9 limits input to nine characters, because you are using a ten-character buffer.
Many answers have told you that scanf("%s",s1) only reads word by word. This is because by default scanf("%s",s1) is delimited by all white spaces, this includes \t, \n, <space>, or any other you can think of.
What scanf("%[^\n]s",s1) does is set the delimiter to \n. So in effect reads all other spaces.
#dasablinklight has also specified a 9 before the '[^\n]' this denotes that scanf() takes 9 values from input buffer.
IMO scanf() is a really nice function due to it's hidden features. I suggest you read more about it in it's documentation.
The problem is that if you type abc def on the first line, the first scanf("%s", s1) (no ampersand required — it should be absent) reads abc and the second reads def. And those are not equal. Type very very and you'd find the words are equal. %s stops reading at a space.
Your buffers of size 10 are too small for comfort.
Fix: read lines (e.g. char s1[1024], s2[1024];) with fgets() or POSIX's getline(), remove trailing newlines (probably: s1[strcspn(s1, "\n")] = '\0'; is a reliable way to do it) and then go ahead compare the lines.

How to capitalize the first letter of each word in an array in C

I am trying to make a simple program that stores a user-input sentence in an array of at most 80 characters and then capitalizes each word of in the sentence. I think I'm on the right track, however when I run the program, only the first word of the sentence is displayed.
#include<stdio.h>
int main(void)
{
int i; /*indexing integer*/
char sen[81]; /*specify total of 80 elements*/
printf("Enter a sentence no longer than 80 characters: \n\n");
scanf("%s",sen);
if((sen[0]>='a') && (sen[0]<='z'))
{
sen[0]=(char)(sen[0]-32); /*-32 in ascii to capitalize*/
}
for(i=0;sen[i]!='\0';i++) /*loop until null character*/
{
if(sen[i]==' ') /*if space: next letter in capitalized*/
{
if((sen[i+1]>='a') && (sen[i+1]<='z'))
sen[i+1]=(char)(sen[i+1]-32);
}
}
printf("%s",sen);
return 0;
}
I have a feeling it is only printing the first word in the array because of the first if statement after the scanf, but I am not completely sure. Any help would be appreciated. Thanks.
By default, the %s conversion specifier causes scanf to stop at the first whitespace character. Therefore you could either use the %80[^\n] format or the fgets function.
#include <stdio.h>
scanf("%80[^\n]", sen);
Or:
#include <stdio.h>
fgets(sen, sizeof sen, stdin);
However, since scanf reads formatted data, human inputs are not suitable for such readings. So fgets should be better here.
I have a feeling it is only printing the first word in the array because of the first if statement after the scanf
No, that's because the %s specifier makes scanf() scan up to the first whitespace. If you want to get an entire line of text, use fgets():
char sen[81];
fgets(sen, sizeof(sen), stdin);
dont use scanf when you want to take multiple words as input: use either gets() or fgets()..
I run your code with gets() and puts() and it worked.

Resources