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]
Related
I am having a c program which print letter by letter of the word. I referred this program from this link
https://www.tutorialgateway.org/c-program-to-print-characters-in-a-string/. If I run this program in online c compiler this gives the exact result, but not working in turbo c++
#include <stdio.h>
int main()
{
char str[100];
printf("\n Please Enter any String : ");
scanf("%s", str);
for(int i = 0; str[i] != '\0'; i++)
{
printf("The Character at %d Index Position = %c \n", i, str[i]);
}
return 0;
}
This program doesn't through any error, but I don't know why this program doesn't print the result.
Try fgets(str, 100, stdin) instead of scanf(). This is the normal way to read a line into a buffer. When I used scanf() I only got part of the output because it will stop reading a string at a space.
IDK what is your output, but here is mine:
Please Enter any String : Hell got loose
The Character at 0 Index Position = H
The Character at 1 Index Position = e
The Character at 2 Index Position = l
The Character at 3 Index Position = l
This is normal, due to this:
Matches a sequence of non-white-space characters; the next pointer must be a pointer to character array that is long enough to hold the input sequence and the terminating null character ('\0'), which is added automatically. The input string stops at white space or at the maximum field width, whichever occurs first.
this is taken from scanf.
EDIT:
Just for the fun, you can do this using scanf
scanf("%[^\n]",str);
this will replace \n newline with '\0'.
NOTE: #Joshua's answer is safer, if you want to know why just google why I shouldn't use scanf()
Trying to take strings as input and place it in 2d array. Why is this given code showing different behavior. The last for loop "arr[i][j]" is not printing the string.It is not even printing a character also.
Why this code does not work.only this code.Not a new way to write it
This code takes input just fine(or at least the way needed.each row a single string no white space)And when a short string is stored remaining are filled with null after carriage return. When the arr[] is passed in last for loop everything seems fine only when arr[][] is passed ,the problem arises.But again arr[][] is initialized as arr[1][0] then arr[2][0] so should not it work!
#include <stdio.h>
#include <stdbool.h>
int main(void){
int i,j,m;
scanf("%d",&m);
char arr[m][50];
for(i=0;i<m;i++){
for(j=0;j<50;j++){
printf("please enter a string");
scanf("%s",&arr[i][j]);
/*j is always 0. arr[i] takes string without space and store ending with null*/
break;
}
}
//Everything fine upto this,including storing a small continuous string in arr[i](where i<50) and null terminating*/
for(i=0;i<m;i++){
for(j=0;j<50;j++){
printf("%s\n",arr[i][j]);
break;
}
}
}
You program has several issues, like using wrong format specifier:
scanf("%s",&arr[i][j]);
arr[i][j] is a character and you are using %s format specifier. If you want your program should take string as input, you just need to do:
scanf("%s",arr[i]);
Since, you have given the size 50 characters, put a restriction in scanf() to not to read more than 49 characters (the remain one character space is for null terminating character) like this:
scanf("%49s",arr[i]);
^^
Beware with this, it does not discard the remaining input from input stream when the input characters are more than 49 and the remaining characters will be consumed by consecutive scanf() call.
If you want to drop the extra input which wasn't consumed by scanf(), one way of doing it is to read and discard the extra input using a loop, like this:
int c;
while((c = getchar()) != '\n' && c != EOF)
/* discard the character */;
In case if you have any doubt on how this will discard the extra input, I would suggest first go through getchar().
Putting all these together, you can do:
#include <stdio.h>
int main(void){
int i,m;
scanf("%d",&m);
char arr[m][50];
for(i=0;i<m;i++){
printf("please enter a string");
scanf("%49s",arr[i]);
int c;
while((c = getchar()) != '\n' && c != EOF) // <=== This loop read the extra input characters and discard them
/* discard the character */;
}
for(i=0;i<m;i++){
printf("%s\n",arr[i]);
}
return 0;
}
EDIT
The below edit is because OP updated question and added - Why this code does not work.only this code.Not a new way to write it
Above in my answer, I have already stated that you are using wrong format specifier in the scanf(). In this part of your code:
for(i=0;i<m;i++){
for(j=0;j<50;j++){ // <====== Nested for loop
printf("please enter a string");
scanf("%s",&arr[i][j]);
// since the nested loop is supposed to run 50 times, assuming you are trying to read character by character and using %s format specifier
break;
// the nested loop will break in the first iteration itself unconditionally, do you really need nested loop here!
}
}
Check the inline comments. Hope this might give an idea of the mistakes you are doing.
Seems that you want to read string character by character using scanf(). If this is the case than make sure to take care of null terminating character because, in C, strings are actually one-dimensional array of characters terminated by a null character '\0'.
You can do:
#include <stdio.h>
void discard_extra_input() {
int c;
while((c = getchar()) != '\n' && c != EOF)
/* discard the character */;
}
int main(void){
int i,j,m;
printf ("Enter number of strings: ");
scanf("%d",&m);
discard_extra_input();
char arr[m][50];
for(i=0;i<m;i++){
printf("please enter string number %d: ", i+1);
for(j=0;j<49;j++){
scanf("%c",&arr[i][j]);
if (arr[i][j] == '\n') {
//need to add null terminating character manually
arr[i][j] = '\0';
break;
}
}
if (j==49) {
// In case where the input from user is more than 50 characters,
// need to add null terminating character manually.
arr[i][j] = '\0';
// discard the extra input when input from user is more than 50 characters.
discard_extra_input();
}
}
for(i=0;i<m;i++){
for(j=0;j<50 && arr[i][j]!='\0';j++){
printf("%c",arr[i][j]);
}
printf ("\n");
}
return 0;
}
The code is self explanatory except one thing - call to discard_extra_input() function after first input from user scanf("%d",&m);. Reason -
Look at the statement:
scanf("%c",&arr[i][j]);
the %c format specifier will consume the leftover newline character '\n' from the input stream due to the ENTER key pressed after first input by the user (number of strings input from user). Hence, in order to discard it, calling discard_extra_input() function. In the other place it has been used to discard the characters when user entered string of size more than 49.
Hope this helps.
I know the code. But looking for specific ans. Where the problem lies with the code
The problem is here:
scanf("%s",&arr[i][j]);
and here:
printf("%s", arr[i][j]);
This is the specific answer you are looking for.
%s won't do any bound checking. It adds the characters starting from the memory location arr + i * m + j to arr + i * m + j + (length of input) + 1 (one extra char for the additional null character that scanf appends). Take a sample input. Assume an arbitrary starting address for arr and do the maths.
Also consider any writes beyond the allocated space for arr leads to undefined behavior.
Similarly printf("%s", arr[i][j]); will try to start reading from the address arr[i][j] till it finds a null character. It would usually lead to crash of the code because if your string has ascii characters, the address would be too low to point to any valid user-mapped memory.
If your code is working, its mostly because you already have a UB in your scanf.
Get a pen and paper and do some dry runs
This is a pretty simple problem buddy. You've got the idea right actually, that you need to use 2d array to store strings. Just that the usage is slightly wrong.
First of all let me tell you how 2d arrays need to be used to store in c. In your 2-D array, you've got rows and columns. Say, row represented by i and columns by j, i.e, each row arr[i] contains j elements. So in your context, each row arr[i] contains each string of upto 50 chars. So scanf should be just for arr[i]. And you need to loop with for, m times to accept m strings.
Same applies to printing as well.
Here is the working code:
#include <stdio.h>
#include <stdbool.h>
int main(void){
int i,j,m;
printf("\nenter m value:");
scanf("%d",&m);
char arr[m][50];
for(i=0;i<m;i++){
printf("\nplease enter a string no %d: ", (i+1));
scanf("%s",arr[i]);
}
printf("\nthe strings are: \n");
for(i=0;i<m;i++){
printf("\n%s\n",arr[i]);
}
}
And the output in case you want to cross check:
OUTPUT:
enter m value: 3
please enter a string no 1: qwerty
please enter a string no 2: asdfgh
please enter a string no 3: zxcvbn
the strings are:
qwerty
asdfgh
zxcvbn
Having a doubt regarding a very simple C code. I wrote a code to calculate the length of a string without using the strlen function. The code below works correctly if i enter a string with no spaces in between. But if i enter a string like "My name is ---", the length shown is the length of the word before the first white space, which in the example, would be 2. Why is that? Aren't white space and null character two different characters? Please guide me as to how i can change the code so that the entire string length is returned?
char s[1000];
int length = 0;
printf ("Enter string : ");
scanf ("%s", s);
for (int i = 0; s[i] != '\0'; i++)
{
length++;
}
printf ("Length of given string : %d", length);
It is because scanf with %s reads until it finds white space.
from man scanf
Matches a sequence of non-white-space characters; the next pointer
must be a pointer to character array that is long enough to hold the
input sequence and the terminating null byte ('\0'), which is added
automatically. The input string stops at white space or at the maximum
field width, whichever occurs first.
If you want read until \n including white space you can do as below.
scanf("%999[^\n]", s);
Or you could use fgets.
scanf reads the data until "\0" or "\20". So use "fgets" method which reads the data until "\n" (next line) with "stdin",
Example Program:
#include <stdio.h>
int main() {
char s[100];
printf("Input String: ");
fgets(s, sizeof(s), stdin);
printf("\nLength of the string is = %d", printf("%s"), s);
return 0;
}
I want a code such that I enter some strings one-by-one (by pressing enter) and display it.
for example;
Input
abc
def
Output
abc
def
also I want this input to be in a array so that I can select any character
from the array whenever I want. For example: s[1][1] gives 'e'.
I have writen a code for this problem.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i, j, n, m;
scanf("%d%d", &n, &m);
char a[n][m];
for (i = 0; i<n; i++)
scanf("%s", a[i]);
for (i = 0; i<n; i++) {
printf("%s", a[i]);
printf("\n");
}
}
But for this code my input/output goes like this:
Input
ab
cd
Output
abcd
cd
Can anyone tell where am I going wrong?
You have not shown the input value of n and m in the question. But from the input and output string shown, it seems that char array a[i] does not have the enough space for terminating null-character \0. When you give format specifier %s, scanf() automatically adds a terminating null character at the end of the stored sequence. I tried your code with input 2 for both n and m and I am getting the output as you are getting:
$ ./a.out
2 2
ab
cd
abcd
cd
Give the value 4 to m and the output is:
2 4
ab
cd
ab
cd
When using scanf() for string input, it is good to add check for max character modifier that is 1 less than the length of the input buffer. So, if the size of input buffer is 4 then you can do
scanf("%3s",a[i]);
With this, the scanf() will read not more than 3 characters in a[i] and will add \0 at the fourth location of a[i]. Beware with this, it does not discard the remaining input from input stream and they will be consumed by consecutive scanf() call.
If you want to drop the extra input which wasn't consumed by scanf, one way of doing it is to read and discard the extra input using a loop, like this:
int c;
while((c = getchar()) != '\n' && c != EOF)
/* discard the character */;
You can add it after scanf() reads data from input stream, like this:
for(i=0; i<n; i++) {
scanf("%3s", a[i]); // assuming the size of a[i] is 4
int c;
while((c = getchar()) != '\n' && c != EOF) // <=== This loop read the extra input characters and discard them
/* discard the character */;
}
This will work fine for the input that does not contain any whitespace characters. If your input contain any whitespace character, it may not behave as expected. Hence, I would suggest you to read about fgets() which gives you better control for string input.
Check this: fgets
and this: How to read from stdin with fgets()?
you are working with a 2D array of char:
char a[n][m];
but keep in mind the value for the 2nd index should be 1 character longer than the length of the string you wish it to allow room for the \0 byte. (all C strings must be null terminated)
This means char a[n][m]; can contain up to n strings, each string with maximum length of m-1 bytes.
char exampleStr[] = {"char count"}; //for example contains 11 characters (not 10)
|c|h|a|r| |c|o|u|n|t|\0| //note nul char is appended
Another common problem when reading user input in a loop is failure to remove any unwanted newlines, which can cause the loop to behave poorly. Following is an example of how to read a user specified number of strings ( using fgets() instead of scanf() ), each with a user specified length: (also removing unwanted newlines ( \n ) in the process)
For readability, the following example replaces n & m with lines & maxLen.
int main(void)
{
int lines, maxLen, i=0;
printf("Enter number of lines:");
scanf(" %d", &lines);
printf("Enter maxLen line length:");
scanf(" %d", &maxLen);
char line[lines][maxLen+2]; //+2 to allow for trailing newline and null
fgets(line[i], maxLen, stdin);//consume anything left in stdout
printf("Enter up to %d characters and hit return:\n%d) ", maxLen, i+1);
for(i=0;i<(lines);i++)
{
fgets(line[i], maxLen, stdin);
line[i][strcspn(line[i], "\n")] = 0; // clear newline
printf("Enter up to %d characters and hit return:\n%d) ", maxLen, i+1);
}
return 0;
}
All strings in C must be terminated with the null character \0, print knows this and prints all character UP TO that sign. You should make all of your strings 1 character longer than the words you plan to fit in them and fill them with 0 (0 is the integer value of \0) in the start to avoid this problem.
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);