I am trying to get an integer separated by space in a string, the sample input and outputs I expected are :
i : word 1
o : 1
i : word 20
o : 20
I tried doing it like this:
scanf("word %d", &num);
but it doesn't work.
I also tried this:
scanf("%[^/]*c%d", &num);
or
scanf("%[^/] %d", &num);
But still, none of them works. Can anyone give me a tip on how to do this? Thanks
Note : the output integer doesn't have a space in front of it.
Full code :
int t, num;
char word[1000];
int arr[100], arr2[100];
fgets(word, 1000, stdin);
scanf("%d", &t);
while(t--){
scanf("word %d", &num);
printf("%d\n", num);
}
As you can see in the above sample code, I am also taking more inputs before taking the input for num.
The first code just needs a space before the scanf text sequence to discard any blank characters that are left in stdin from previous reads, you can, however, improve it further to recongize bad inputs and discard them if that is the case:
while(t){
if(scanf(" word %d", &num) == 1){ //space before word
printf("%d\n", num);
t--;
}
}
But if you want to use that regex specifier you cand do something like:
while(t){
if(scanf("%*[^ ]%d", &num)){
printf("%d\n", num);
t--;
}
}
This would work not only for word but for any other string, provided that it only has one word, i.e. no spaces, apart from the one in the end.
Related
I'm writing a program that asks the number of strings which i'll then count how many spaces it has.
My problem is when I start a new cycle I can't allocate the array of characters I use to count the spaces.
Thanks in advance.
#include <stdio.h>
#include <string.h>
int main(){
char a[20];
int x, z, esp=0, num;
scanf("%d\n", &num);
int array[num];
for (int i=0;i<num;i++){
scanf("%[^\n]", &a);
z =strlen(a);
for (x=0; x<=z; x++){
if (a[x] == ' '){
esp++;
}
}
array[i] = esp;
esp =0;
}
for (int i=0;i<num;i++){
printf ("%d\n", array[i]);
}
return 0;
}
Problems:
Not having all warnings enabled. Save time, enable them all.
'\n' blocks for more input in scanf("%d\n", &num);
Not checking scanf() return value.
Not limiting input with a width in scanf("%[^\n]", &a);
Wrong type passed in scanf("%[^\n]", &a);
Big one: not consuming the end-of-line with repeated scanf("%[^\n]", &a); calls.
Perhaps more.
Repaired code:
// scanf("%d\n", &num);
if (scanf("%d", &num) != 1) { // '\n' removed
puts("Error1");
return -1;
}
// scanf("%[^\n]", &a);
if (scanf(" %19[^\n]", a) != 1) { // ' ' consumes white-space like \n
puts("Error2");
return -1;
}
On the first scanf, remove \n character, after the first scanf, add getchar() to consume new line character.
Replace second scanf with gets;
Then it will work correctly.
By the way, since gets is unsafe, you can use fgets with stdin parameter and max character count parameter instead of gets.
Thanks to everyone who commented and answered my question, I think I wasn't able to explain myself properly. It's a code which reads a number, the number of the lines of characters which then it'll count the spaces of; my problem started when the code executes a new cycle in which this scanf didn't let me enter the string of characters again: scanf("%[^\n]", &a), but did everything else in the cycle while using the same string.
I'm really new to this, coding and the page itself so thanks for the advices. I was able to find a solution: scanf("%[^\n]%*c, &a)
%*[^\n] scans everything until a \n, but doesn't scan in the \n. The asterisk(*) tells it to discard whatever was scanned.
%*c scans a single character, which will be the \n left over by %*[^\n] in this case. The asterisk instructs scanf to discard the scanned character.
And here is the updated code:
#include <stdio.h>
#include <string.h>
int main(){
char a[20];
int x, z, esp=0, num;
scanf("%d\n", &num);
int array[num];
for (int i=0;i<num;i++){
scanf("%[^\n]%*c", &a);
z =strlen(a);
for (x=0; x<=z; x++){
if (a[x] == ' '){
esp++;
}
}
array[i] = esp;
esp =0;
}
for (int i=0;i<num;i++){
printf ("%d\n", array[i]);
}
return 0;
}
I'm trying to make a simple voucher. So, I used a multidimensional string. But facing trouble including space in those strings. Instead, I took words as input. But is there any way to include space? My code is given below-
#include<stdio.h>
#include<string.h>
int main(){
int sum =0, n, i;
puts("Please input how many transactions you want to enlist: ");
scanf("%d", &n);
char list[301][51];
int amount[301];
puts("Please enter the name of your transaction and the amount: (Press space or enter to toggle between name and amount . And avoid using spaces in the name; use underscore instead.)");
for(i=0; i<n; i++){
scanf("%s %d", &list[i], &amount[i]);
sum += amount[i];
}
list[0][n+1] = '\0';
amount[n+1] = '\0';
puts("");
printf("\t\t\t\t Voucher\n\n");
puts(" Ser.|\t Name \t\t\t\t\t\t\t|Amount");
puts("------------------------------------------------------------------------------------------------------------");
for(i=0; i<n; i++ ){
printf(" %03d |\t %-50s\t|%6d\n", i+1, list[i], amount[i]);
}
puts("------------------------------------------------------------------------------------------------------------");
printf(" | Total\t\t\t\t\t\t\t|%6d", sum);
puts("");
return 0;
}
For this you could use the %[ scanf specifier, to read all characters until you hit a digit, and write it into list[i].
This will leave you with a trailing space in list[i], but that can be trimmed if you don't want it.
The scanf call could then look something like
scanf(" %50[^0-9]%d", list[i], &amount[i]);
Note the leading space in the format string, to tell scanf to skip white-space (like the newline from the previous line), and the width-specifier to not read more than can fit in line[i].
Of course, that prevents you from having numbers inside the string you read. To solve this problem you need to go a more complicated route.
For example by reading the whole line into a buffer, and then find the last space in the string. You can then copy the contents before the last space to list[i], and convert the contents after to an int value for amount[i].
It takes in a word and a number, I can't seem to understand why the number variable won't receive the input, help please.
#include <stdio.h>
int main(void) {
char userWord[20];
int userNum;
scanf("%s", userWord);
printf("%s_", userWord);
scanf("%s", userNum);
printf("%d\n", userNum);
return 0;
}
Should be:
Input: Stop 7
Output: Stop_7
What I get:
Input: Stop 7
Output: Stop_0
Change
scanf("%s", userNum);
to
scanf("%d", &userNum);
You used format %s for reading in an integral value; it should have been %d.
Once having fixed this (i.e. by writing scanf("%d", &userNum);, note that your code will read in a string and a number even if the string and the number were not in the same line (cf., for example, cppreferene/scanf concerning format %s and treatment of white spaces). Further, you will run into undefined behaviour if a user enters a string with more than 19 characters (without any white space in between), because you then exceed your userWord-array.
To overcome both, you could read in a line with fgets, then use sscanf to parse the line. Note that you can parse the line in one command; the result of scanf is then the number of successfully read items. Further, note the %19s, which limits the input to 19 characters (+ the final string termination character '\0'):
int main() {
char line[100];
if (fgets(line,100,stdin)) {
char userWord[20];
int userNum;
if (sscanf(line, "%19s %d", userWord, &userNum) != 2) {
printf("invalid input.\n");
} else {
printf("word:'%s'; number: %d", userWord, userNum);
}
}
}
as expected this prog. should accept a number until it encounters a 4 but it gives some garbage value. why?
int main(void)
{
int a;
printf("Enter a number: ");
scanf("%[^4]d", &a);
printf("You entered: %d\n", a);
return 0;
}
As far as I know scansets are meant to be used with strings (which makes the d not act as an integer placeholder specification). One way to write it is to read the input into a string and then parse it:
int main(void)
{
int a;
char b[255];
printf("Enter a number: ");
scanf("%254[^4]", &b);
a = atoi(b);
printf("You entered: %d\n", a);
return 0;
}
I'm keeping the modified code to a minimum, you'd definitely need some extra checks for input sanity.
To clarify: The 254 prefix limits the amount of data that scanf will capture, so as to not exceed the size of the buffer (strings are terminated with an extra null character, so the read length must be smaller than the actual size)1.
The scanset working with only characters.
Here is my sample code. (but, I don't know what you really want.)
#include <stdio.h>
int main(void) {
char buffer[128];
printf("Enter a number: ");
scanf("%[^4]s", buffer);
printf("You entered: %s\n", buffer);
return 0;
}
The result is,
Enter a number: 12345678
You entered: 123
Additionally, if you want integer value, use atoi().
I'm doing an exercise in C but I have a problem when at the and I want to repeat the cicle (do while), infact if I type 1 the programme starts again by the top, but it doesn't stop at the gets(testo); . I tried plenty of ways to solve the bug without a solution, can anyone help me?
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
main(){
int cch, cw, i, j, w, ord, f; //counter and index
char testo[80];
char alfa[50][25];
char swap[25];
do{
cch=0;
cw=0;
j=0;
w=0;
f=0;
for(i=0;i<80;i++){
testo[i]='\0';
}
printf("Write the text:\n");
gets(testo);
//initialization 2d array
for(i=0;i<50;i++){
for(j=0;j<25;j++){
alfa[i][j]='\0';
}
}
j=0;
//Count word and characters
if(testo[0]!='\0'){
cw=1;
for(i=0;testo[i]!='\0';i++){
cch++;
if(testo[i]==' '){
cw++;
j++;
}
}
}
if(cch==j){
printf("You haven't written any word\n\n");
}
else{
//Don't count double space
for(i=0;i<cch;i++){
if(testo[i]==' ' && testo[i+1]==' '){
cw--;
}
}
//Don't count as word if the text start with a space
if(testo[0]==' '){
cw--;
w--;
}
printf("\nThe text is composed by %d characters\n", cch);
printf("The text is composed by %d words\n", cw);
if(cw>0){
printf("\nUsed words:\n");
for(j=0;j<cch;j++){
if(testo[j]==' ' && testo[j+1]==' '){
//nothing to do
}
else{
if(testo[j]!=' '){
alfa[w][f]=testo[j];
f++;
}
else if(testo[j]=='\0'){
alfa[w][f]='\0';
f=0;
w=0;
}
else{
alfa[w][f]='\0';
w++;
f=0;
}
}
}
for(i=0;i<cw;i++){
printf("%d> %s\n", i+1, &alfa[i]);
}
//order
f=1;
printf("\nWords used in alphabetical order:\n");
while(f==1){
f=0;
for(i=0;i<cw-1;i++){
ord=strcmp(alfa[i],alfa[i+1]);
if(ord>0){
strcpy(swap,alfa[i]);
strcpy(alfa[i],alfa[i+1]);
strcpy(alfa[i+1],swap);
f=1;
}
}
}
for(i=0;i<cw;i++){
printf("%d> %s\n", i+1, alfa[i]);
}
}
}
printf("\nDo you want write another text? (1=yes) -> ");
scanf("%d", &j);
}while(j==1);
}
I know that isn't very optimized as code at the moment and has other errors, but I'm having problem on this.
Thank you.
PS: The code is tested on OpenVMS
It's because the scanf call at the end of the loop doesn't read the newline. Instead this newline is read by your gets call.
A simple solution is to add a space to the end of the scanf format string, like so:
scanf("%d ", &j);
This will make scanf skip trailing whitespace in the input.
Another solution is to put an extra fgets after the scanf, but then don't add the extra space in the format string:
scanf("%d", &j);
fgets(testo, sizeof(testo), stdin);
Or use fgets to get the line, and then use sscanf to extract the answer:
fgets(testo, sizeof(testo), stdin);
sscanf(testo, "%d", &j);
Your first and most obvious problem is with the left over newline. When you use scanf() here:
printf("\nDo you want write another text? (1=yes) -> ");
scanf("%d", &j);
}
and you use the %d format specificer, the function is looking for a number, when you enter a number really you're entering a number and a newline character
> 1<enter key> // which means on stdin you're getting '1''\n'
scanf() only picks up the 1 and leaves the newline which your gets() function then picks up, so it looks like it's skipping the input. All you need to do is consume that newline character, one quick fix would be to consume it with getchar():
printf("\nDo you want write another text? (1=yes) -> ");
scanf("%d", &j);
getchar();
}
Now your program works as you'd expect.
Other issues of note:
Your main should really be returning an int type, even if it's just a return 0
You shouldn't be using gets(), even then man page for gets() says Never use gets(). That's usually a good indication not to. ;) So replace that line with fgets(testo, sizeof(testo), stdin);
You missed a performance specificer here: printf("\nThe text is composed by % characters\n", cch); so you're getting garbage output, that should have been %d
Or you can try using the function flushall() just before gets()