How can I introduce multiple strings with scanf() in the easiest way? - c

How can I introduce multiple strings in input and output with scanf()? Is it possible to do that without using 100 notations (e.g. a, b, c, d, e -> "%c %c %c", a, b, c etc.)?
I type this:
#include <stdio.h>
int main()
{
char user_str[20];
scanf("%s", user_str);
printf("%s", user_str);
return 0;
}
Which works for the first word as input and output, but if I want to introduce 100 propositions with space in the text, how can I type the code to do that in the easiest way possible?

As #Yunnosch notes, your best best is to use loops and arrays. Consider a simple situation where you want to read in 4 strings that are up to 19 characters in length. We have length 20 to leave space for a terminating null character.
#include <stdio.h>
int main() {
char input[4][20];
for (int i = 0; i < 4; i++) {
scanf("%19s", input[i]);
}
for (int i = 0; i < 4; i++) {
printf("%s\n", input[i]);
}
}
This is readily scalable to 100s of strings. If you use enough memory, you may wish to use malloc to allocate it, but the same basic pattern would continue.

Here is a solution which reads one line of input using scanf:
#include <stdio.h>
int main()
{
char user_str[20];
scanf("%[^\n]s", user_str);
printf("%s", user_str);
return 0;
}
Using %[^\n]s instead of %s will read all characters until you reach \n (or EOF ) and write them into user_str. But this solution is worse than gets(), so try to use fgets() instead.
#include <stdio.h>
int main()
{
char user_str[100];
printf("Enter your name: ");
fgets(user_str, 100, stdin);
printf("Your Name is: %s", user_str);
return 0;
}

Related

Frequency function in C

I wrote a program that should take a string and a letter, then call a function which have two parameters (the string, the letter) and then count frequency of letter in the string.
The problem with my code is that it always returns num with value zero for any letter.
#include <stdio.h>
#include <stdlib.h>
int Occur(char [], char);
int main()
{
char s[100], l;
printf("Enter A String:\n");
scanf("%s",s);
printf("Enter A Letter:\n");
scanf("%c",&l);
getchar();
printf("Num Of Occurance is %d ",Occur(s,l));
return 0;
}
int Occur(char S[100], char L)
{
int i;
int num=0;
for(i=0; S[i]!='\0'; i++)
{
if(S[i]==L)
num++;
}
return num;
}
First, you should have tried debugging your code. If you would have done it, you would have seen that the letter you thought L holds is not what L actually holds.
Second, your problem is simple, L is not getting the letter you enter because of the enter from the string before is stuck in the scanf buffer... use scanf (" %c") [with preceeding whitespace] to resolve.
As mentioned in other answers, there are other solutions like the unrecommended fflush(). An alternative that is not considered harmful is getchar() between the scanf("%s") and the scanf("%c"). That will give you the same effect as using scanf(" %c");
The reason that all of these methods work is because they all consume the last char (which is, in your case the \n) stuck in the buffer, and thus allowing the %c to consume the char you actually intend to read
Reason of problem :
scanf("%c",&l) //Here %c takes enter key of scanf("%s",s);;
So, there are mainly 2 solution to your problem:
Sol. 1 => scanf(" %c",&l) //use whitespace before %c
Sol. 2 => Use fflush(stdin) that flushes the output buffer of a stream.
int main()
{
char s[100],l;
printf("Enter A String:\n");
scanf("%s",s);
printf("Enter A Letter:\n");
fflush(stdin); //here fflush(stdin) used to flushes the output buffer.
scanf("%c",&l);
l = getchar();
......
......
}
NOte: Since fflush(stdin) has undefined behavior so, always use priority to Solution 1 , instead of fflush(). :)
It's an input buffer problem. The char is read by getchar instead of scanf.
Doing l = getchar() solves the problem (the call of scanf just before clears the input buffer).
#include <stdio.h>
#include <stdlib.h>
int Occur(char [],char);
int main()
{
char s[100],l;
printf("Enter A String:\n");
scanf("%s",s);
printf("Enter A Letter:\n");
scanf("%c",&l);
l = getchar();
printf("Num Of Occurance is %d ",Occur(s,l));
return 0;
}
int Occur(char S[100],char L){
int i;
int num=0;
for(i=0;S[i]!='\0';i++){
if(S[i]==L)
num++;
}
return num;
}
Your function definition is wrong in terms of good code practices.
Instead of
int Occur(char S[100], char L)
You should write it as
int Occur(char S[] , char L)
because otherwise your code would specifically look to accept strings of size not more than 100 chars.
Apart from that as Ilario Pierbattista said its a input buffer problem.
The stdin needs to get cleared before taking further input, hence the juggad of putting scanf before a getchar() call would work.

Which format should I use: scanf \string,string,int,int/?

I have data in the following format \a,b,c,d/ where a,b are strings of letters and numbers; c, d are integers.
I tried using format \%s,%s,%d,%d/ format to scan it, but that causes a,b,c,d/ to be scanf'ed into the first string instead of only a.
Question:
Is there something I could type in the format in order to achieve desired result?
You can use the following format string to use commas as delimiters :
"\\%[^,],%[^,],%d,%d/"
The idea is to tell scanf to read anything that isn't a comma for each string, then read the delimiting comma and continue.
Here is a (bad and unsafe!) example:
char a[100], b[100];
int c=0, d=0;
scanf("\\%[^','],%[^','],%d,%d/", a, b, &c, &d);
printf("%s, %s, %d, %d\n", a, b, c, d);
In real code, you'll want to write something safer. You can for example use fgets to read a full line of input then reuse the same format string with sscanf to parse it.
Read carefully the documentation of fscanf(3).
You might try something like
char str1[80];
char str2[80];
memset (str1, 0, sizeof(str1));
memset (str2, 0, sizeof(str2));
int n3 = 0, n4 = 0;
int pos = -1;
if (scanf ("\\ %79[A-Za-z0-9], %79[A-Za-z0-9], %d, %d /%n",
str1, str2, &n3, &n4, &pos) >= 4
&& pos > 0) {
// be happy with your input
}
else {
// input failure
}
That won't work if you have a wider notion of letters, like French é or Russian Ы ; both are single letters existing in UTF-8 but represented in several bytes.
I added some spaces (mostly for readability) in the format string (but scanf is often skipping spaces anyway, e.g. for %d). If you don't accept spaces -like an input line such as \AB3T, C54x, 234, 65/ , read each line with getline(3) or fgets(3) and parse it manually (perhaps with the help of sscanf and strtol ...). Notice that %d is skipping spaces! I also am clearing the variables to get more deterministic behavior. Notice that %n gives you the amount of read characters (actually, bytes!) and that scanf returns the number of scanned items.
My straightforward solution:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char a[10010];
gets(a);
int l = strlen(a);
char storded_first[10010], storded_second[10010];
char for_int_c[10010], for_int_d[10010];
int c,d;
char first_symbol, last_symbol;
int i;
int cnt = 0;
int j=0;
for(i=0; i<l; i++)
{
if(a[i]=='\\')
first_symbol = a[i];
else if(a[i]=='/')
last_symbol = a[i];
else if(a[i]==',')
{
cnt++;
j=0;
}
else if(cnt==0)
{
storded_first[j]=a[i];
j++;
}
else if(cnt==1)
{
storded_second[j]=a[i];
j++;
}
else if(cnt==2)
{
for_int_c[j]=a[i];
j++;
}
else if(cnt==3)
{
for_int_d[j]=a[i];
j++;
}
}
c = atoi(for_int_c);
d = atoi(for_int_d);
printf("%c%s, %s, %d, %d%c\n",first_symbol, storded_first, storded_second, c, d, last_symbol);
return 0;
}

Read several ASCII characters and get the value

Can someone explain or correct me on the code i have?
I'm trying to input several characters and get the ascii value
ex: input: ab; output:9798
This is my code but there's a 10 at the end of it
#include <stdio.h>
int main() {
char c;
printf("Enter any character\n");
for (c=0; c<=122; c++)
{
scanf("%c", &c);
printf("%d",c);
}
return 0;
}
If you look at ASCII table, a decimal value of 10 is a newline character. In other words, you process \n character as part of the input. This can happen when user copy-pastes multiple lines, or when Enter key is pressed, for example. If you do not want that to happen, you need to take extra care to ignore \n. For example:
#include <stdio.h>
int main() {
char c;
printf("Enter any character\n");
for (c=0; c<=122; c++)
{
scanf("%c", &c);
if (c == '\n')
break; /* Or perhaps continue? Depends on what you actually want. */
printf("%d",c);
}
return 0;
}
Also, note that different systems may have different conventions as for what newline actually is. On UNIX, it is \n character only, on Windows, it might be a combination or \r and \n. So if you want to make your program portable, this needs to be taken into account. You can either do it yourself, or use some other library (GNU getline comes to mind). You can read more about newline here.
You may want to exclude some chars from the output and not only '\n', in that case you can try something like this:
#include <stdio.h>
int isEndingChar(char c) {
char terminators[3] = {'\r','\t','\n'}
int n;
for( n=0; n<3; n++ ) {
if( terminators[i]==c )
return 1;
}
return 0;
}
int main() {
char c;
printf("Enter any character\n");
for (c=0; c<=122; c++)
{
scanf("%c", &c);
if( isEndingChar( c ) )
break;
printf("%d",c);
}
return 0;
}

How to read from input until newline is found using scanf()?

I was asked to do a work in C when I'm supposed to read from input until there's a space and then until the user presses enter.
If I do this:
scanf("%2000s %2000s", a, b);
It will follow the 1st rule but not the 2nd.
If I write:
I am smart
What I get is equivalent to:
a = "I";
b = "am";
But It should be:
a = "I";
b = "am smart";
I already tried:
scanf("%2000s %2000[^\n]\n", a, b);
and
scanf("%2000s %2000[^\0]\0", a, b);
In the 1st one, it waits for the user to press Ctrl+D (to send EOF) and that's not what I want.
In the 2nd one, it won't compile. According to the compiler:
warning: no closing ‘]’ for ‘%[’ format
Any good way to solve this?
scanf (and cousins) have one slightly strange characteristic: white space in (most placed in) the format string matches an arbitrary amount of white space in the input. As it happens, at least in the default "C" locale, a new-line is classified as white space.
This means the trailing '\n' is trying to match not only a new-line, but any succeeding white-space as well. It won't be considered matched until you signal the end of the input, or else enter some non-white space character.
One way to deal with that is something like this:
scanf("%2000s %2000[^\n]%c", a, b, &c);
if (c=='\n')
// we read the whole line
else
// the rest of the line was more than 2000 characters long. `c` contains a
// character from the input, and there's potentially more after that as well.
Depending on the situation, you might also want to check the return value from scanf, which tells you the number of conversions that were successful. In this case, you'd be looking for 3 to indicate that all the conversions were successful.
scanf("%2000s %2000[^\n]", a, b);
use getchar and a while that look like this
while(x = getchar())
{
if(x == '\n'||x == '\0')
do what you need when space or return is detected
else
mystring.append(x)
}
Sorry if I wrote a pseudo-code but I don't work with C language from a while.
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
int main(void)
{
int i = 0;
char *a = (char *) malloc(sizeof(char) * 1024);
while (1) {
scanf("%c", &a[i]);
if (a[i] == '\n') {
break;
}
else {
i++;
}
}
a[i] = '\0';
i = 0;
printf("\n");
while (a[i] != '\0') {
printf("%c", a[i]);
i++;
}
free(a);
getch();
return 0;
}
I am too late, but you can try this approach as well.
#include <stdio.h>
#include <stdlib.h>
int main() {
int i=0, j=0, arr[100];
char temp;
while(scanf("%d%c", &arr[i], &temp)){
i++;
if(temp=='\n'){
break;
}
}
for(j=0; j<i; j++) {
printf("%d ", arr[j]);
}
return 0;
}
#include <stdio.h>
int main()
{
char a[5],b[10];
scanf("%2000s %2000[^\n]s",a,b);
printf("a=%s b=%s",a,b);
}
Just write s in place of \n :)
//increase char array size if u want take more no. of characters.
#include <stdio.h>
int main()
{
char s[10],s1[10];
scanf("\n");//imp for below statement to work
scanf("%[^\n]%c",s);//to take input till the you click enter
scanf("%s",s1);//to take input till a space
printf("%s",s);
printf("%s",s1);
return 0;
}

Counting characters in C

I'm trying to write a program that counts all the characters in a string. I originally had it, but then realized I can't count spaces. I can't see why this does not work.
for(m=0; z[m] != 0; m++) {
if(z[m] != ' ') {
charcount ++;
}
}
Any assistance appreciated.
Edit* Does it make a difference if the input(strings) are being scanned in like this? And yes, everything is initialized. I've tried printing what z[m] evaluates too and it isn't the actual value of the string at "m", I think this is the problem.
for(j=0; j<7; j++){
printf("Enter a string:\n");
scanf("%s", z);
for(m=0; z[m] != 0; m++){
if(z[m] != ' '){
charcount ++;
}
}
You need to initialize charcount. Other than that, it should work, provided that z is a zero-terminated array of characters and m is an int or similar. I would probably write just z[m] rather than z[m] != 0 (since !0 = true and 0 = false), but both work. There are more efficient ways of doing it (although these days I bet a compiler will handle converting this into a pointer-based loop for you).
Here's a complete, correct example with minimal edits:
const char * z = "testing one two three";
int m;
int charcount;
charcount = 0;
for(m=0; z[m]; m++) {
if(z[m] != ' ') {
charcount ++;
}
}
If you're using a String class of some kind rather than an old-fashioned C null-terminated array, you'll want to look at that class for how to loop through it.
All of the above also assumes you're dealing with ASCII strings. If you're dealing with UTF-encoded strings, you have to handle multi-byte characters.
Re your edit: It makes a big difference: scanf will stop on the first blank (I'd forgotten that). It might make an even bigger difference than that, though, if you're not declaring z correctly. (I'd also recommend using a field width when using scanf for reading strings [or avoiding scanf entirely]; otherwise, you have no control over the number of chars it will try to store, and so in theory, no buffer will ever be big enough to avoid an overflow. More here: http://www.crasseux.com/books/ctutorial/String-overflows-with-scanf.html)
You can use strlen()
I'd suggest using a while loop, and to use more meaningful variable names
m = textIndex
z = text
Something like this would work
while (text[textIndex] != 0x00)
{
textIndex++;
}
Instead of using scanf, try fgets like so:
char input[256];
fgets(input, sizeof(input), stdin);
fgets will read an entire line from a file. As such, passing stdin as the file handle will make it read from standard input, which in most cases will be bound to the console. One thing to watch out for, though, is that the string you get from fgets might include the newline character. Rather than explicitly checking your strings for inequality with the space character (' '), I suggest using the isspace function from ctype.h, which will check for various forms of whitespace (including a regular space and newline).
Here is a complete, runnable example:
#include <stdio.h>
#include <ctype.h>
int count_nonspace(const char* str)
{
int count = 0;
while(*str)
{
if(!isspace(*str++))
count++;
}
return count;
}
int main()
{
char input[256];
fgets(input, sizeof(input), stdin);
printf("%d\n", count_nonspace(input));
}
Yes, there is a difference on input-scan with scanf:
scanf("%s", z);
...
if(z[m] != ' '){
scanf("%s"...) always breaks at space-character, therefore your if ever is true. Better you use fgets to read from stdin,
#define MAXINPUT 80
char line[MAXINPUT];
for(j=0; j<7; j++) {
printf("Enter a string:\n");
if( fgets( line, 80, stdin ) )
{
char *c=line;
if( strchr(line,'\n') ) *strchr(line,'\n')=0;
while( *c )
{
if( *c!=' ' )
++charcount;
++c;
}
}
}
Or if you want WHITE -spaces then take
#include <ctype.h>
...
if( !isspace(*c) )
this seems to work for me, its a simple 30 line code that is in a loop and can detect the letter of choice for the chosen string/sentence/word the user has inputted.
#include <stdio.h>
#include <string.h>
int main(){
while(true){
char string[100];
char letter[100];
int count = 0;
printf("Enter a word/sentence:\n");
scanf(" %[^\n]s",string);
printf("Enter a letter:\n");
scanf(" %c",&letter); //when using scanf for a sentence/word or character, always include a space afterwards.
//Counts each character except space
for(int i = 0; i < strlen(string); i++) {
if(string[i] == letter[0]){
count++;
}
}
//Displays the total number of characters present in the given string
printf("Total number of characters in the string: %d\n", count);
printf("%s\n",string);
}
return 0;
}

Resources