Reading time as character array in c - c

I am a newbie to C character arrays. And I know that to read character arrays we need to use %s format specifier using scanf or gets.
I am reading time as two character array's in C as h[2] and m[2] where h represents hours and m represents minutes.
char h[2],m[2];
scanf("%s:%s",h,m);
printf("%s:%s",h,m);
But when I give 11:30 as input it prints time as 11:30::30 as output. Can anyone say me the reason?
Thank you.

You are forgetting to do a few things:
Your character arrays need to be null terminated. Create h and m with a size of 3 instead of 2, allowing for a null character, '\0', to be placed after the string. scanf does this for you.
You can limit the size of the input string with scanf. scanf("%2s", h) would place a string of 2 characters from stdin into h.
You could also exclude the : character from the first string: scanf("%[^:]:%s", h, m)
Putting all of this together, we get:
char h[3], m[3]; // Create two character arrays of 3 characters.
if (scanf("%2[^:]:%2s", h, m) == 2) { // Read the time given and check that two items were read (as suggested by chux)
printf("%s:%s", h, m); // Print the time given.
}

try this two options, i hope they will satisfy you:
1-
char h[3], m[3];
printf("Input time\n");
scanf("%s%s", &h, &m);
printf("\n%s:%s\n", h, m);
return 0;
2-
int i;
char ch, hour[6];
printf("Input time\nex. HH:MM\n");
while(ch!='\n')
{
ch=getchar();
hour[i]=ch;
i++;
}
hour[i]='\0';
printf("\n");
printf("Time: %s\n", hour);
return 0;

Related

Why my program doesn't allow me to input b?

I want to input valors for a and b, being a an int and b a str. When I run my program I can input a valor, but then it ingnores printf() and gets() for b.
#include<stdio.h>>
int main()
{
int a;
char b[5];
printf("Write a:\n");
scanf("%i", &a);
printf("Write b:\n");
gets(b);
printf("a = %i, b = %s", a, b);
return 0;
}
In the end, it just prints:
a = (valor written), b =
I don't know what's wrong with this, neither if it's a different way to get this working. I'm pretty new with C. Thank you in advance. ;)
The function gets is unsafe and is not supported by the C Standard. Instead use either scanf or fgets.
As for your problem then after this call of scanf
scanf("%i", &a);
the input buffer contains the new line character '\n' that corresponds to the pressed key Enter. And the following call of gets reads an empty string by encountering the new line character.
Instead of using gets write
scanf( " %4[^\n]", b );
Pay attention to the leading space in the format string. It allows to skip white space characters as for example the new line character '\n'. And the call of scanf can read a string with maximum length equal to 4. If you want to read a larger string then enlarge the array b and the field width specifier in the format string.

replacing elements of a string in C

The Spinx brothers have planted a bomb in Tokyo’s Metropolitan Police Headquarters. Quite
conveniently, they left behind a string S (encrypted, of course) as the key to defuse the bomb, but
there is more to it.
The police from their previous encounters with the Sphinx brothers have deduced a possible
decryption. Some of the letters in the string need to be replaced with some other letter in accordance
with the decryption pattern. It is possible that a decrypted letter can be decrypted/replaced again.
You need to replace each letter in the string until it cannot further be replaced, to obtain the key.
They challenge you to do this as quickly as possible, as the bomb in the headquarters is about to
explode any time now.
Input
The first line has the string S (1 ≤ |S| ≤ 105) consisting of lowercase letters only. The next line has a
single integer M (1 ≤ M ≤ 325), denoting the number of replacements. The next M lines have two
spaced characters, ci and di, with di being the replacement of ci.
Output
Print the final string after all character replacements.
Note
It is guaranteed that there are no cyclic replacements.
input
nineandeleven
5
n l
l u
u w
e a
a y
output
wiwyywdywyvyw
This is how I coded it. I couldn't take more than 3 rows of inputs
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(){
char str[100000];
scanf("%s",str);
int M;
char x,y;
scanf("%d",&M);
for(int i=0;i<M;i++){
scanf("%c %c",&x,&y);
for(int j=0;j<strlen(str);j++){
if(str[j] == x) { str[j]=y;}
}
}
printf("%s",str);
return 0;
}
scanf("%c %c",&x,&y);
change to
scanf(" %c %c",&x,&y);
one more space
because when you enter "enter"
will push newline(windows.linux may be little different like \t\n \n if you want to know google it) to your buffer
when you use %c will read last you push not jump space, '\n', '\t'
when you add space in front of %c
scanf will jump space, '\n', '\t' before read buffer then will get correct your input by your keyboard
maybe its a bug i didnt it like that before seems you increment the index in the first %c scanf
there is a solution u can use strtok(str, delimiter) in string.h each time scan the whole string like "l p" then split it with the white spase
char d[3];
scanf("%s", d);
x = s[0];
y = s[2];
then increment your index etc..
or split it
char *token;
char d[3];
scanf("%s", d);
token = strtok(d, ' ');
x = token[0];
y = token[1];
Good Luck

C multidimensional array pointing problem?

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

Scanf won't notice '\n' char in a program loading only numbers

I have been searching for a few days and I have found only one solution that didn't look perfect to me. Our teacher asked us to create a function that would calculate total lenght of distances in between points provided by user.
My idea was to write code this way, using an array of specific type.
The issue is that, I can't come up with any ideas for how to solve the issue with input: He asked us to make the program end once the user doesn't type anything, so I take it for enter - \n sign.
I could use fgets to get the first variable but:
First, I feel like I don't know any other way beside an array for keeping a long decimal number(in a form of a char array with elements making up the number), that the user could put on the input. I don't know if his script doesn't put some "rofl" number in there.
Second, in this case I think that stripping that array off one X would totally break the total structure of this program. I would rather take both X and Y and accept them as char type, but then the function like atof would probably understand only the X and would stop working after the \n sign.
So Y would be left not given. The accepted input numbers should be of double type. Like:
2 2
3 3
-2 4.5
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
double lenght(struct point *coordinates, int n);
struct point {
double x;
double y;
};
int main()
{
double x,y,TwiceAsBig=3;
int i=0,l=0;
struct point *coordinates;
coordinates = (struct point*)malloc(sizeof(*coordinates)*3);
//allocation of memory for pointtype array with a pointer
while(scanf("%lg %lg",&x,&y)==2)
{
coordinates[i].x=x;
coordinates[i].y=y;
i++;
if(i==TwiceAsBig)
{
coordinates = (struct point*)realloc(coordinates, 2*i*sizeof(*coordinates));
TwiceAsBig=2*TwiceAsBig;
}
}
printf("\n");
for(l;l<i;l++)
{
printf("%lg %lg\n", coordinates[l].x,coordinates[l].y);
}
//checking on the array if the values were loaded correctly
printf("%lg",lenght(coordinates,i));
}
//function for dinstace in between the points
double lenght(struct point*coordinates,int n)
{
int l=0;
for(l;l<n;l++)
{
printf("%lg %lg\n", coordinates[l].x,coordinates[l].y);
}
int pair=0;
double lenght,distance;
for(int AoP;AoP<n-1;AoP++)
{
distance=sqrt(pow(coordinates[pair+1].x-coordinates[pair].x,2)+pow(coordinates[pair+1].y-coordinates[pair].y,2));
pair++;
printf("%lg: ", distance);
lenght=lenght+distance;
}
return lenght;
}
As for your problem, using fgets to read a whole line, and the possibly use sscanf to parse out the two numbers might work.
The problem with using only scanf is that all the numeric format specifiers reads and skips leading white-space automatically, and newline is a white-space character. That means your scanf call in the loop condition will wait until there's some actual non-space characters being input (followed by a newline of course, which leads to the cycle starting over again).
What about using scanf("%[^\n]%*c", test); to read a full string.
Then parsing the result using sscanf?
Something like this:
char* userinput = (char*) malloc(sizeof(char) * 100);
scanf("%[^\n]%*c", userinput);
double a, b;
sscanf(userinput, "%lg %lg", &a, &b);
printf("sum %lg\n", a+b);
With input "-5.5 3.2" the code produces "sum -2.3".
%[^\n]%*c is a "scanset" which tells scanf to read everything excluding '\n' and once it reaches a newline it reads the newline character and disregards it.
You could even use scansets to check the input to some degree by specifying which type of characters you expect to read.
%[0-9 .\\-] // would read digits from 0-9, 'space', '.' and '-'

Is it possible to get two inputs of different datatypes in one scanf() in c?

I want to get the command as input like
<char><number><number>
so is it possible to get it using one scanf() function in c ?
int i,j;
char c;
scanf("%c%d%d",&c, &i, &j);
I don't think that will work because the compiler will consider that as something together rather than one character, and two integers but to take the input in this format i.e. to make the compiler understand that you can take the entire line as a string and then parse the string to extract the character and the integers
char a[1000],c; int x,y;
scanf("%s",a);
c = a[0];
x = a[1] - '0';
y = a[2] - '0';
Also, #BLUEPIXY gave even better solution to your problem!
You can get more than 1 input in 1 scanf as the following:
char ch, string[100];
int number;
printf("--char--/--number--/--string--");
scanf(" %c%d %s",&ch,&number,&string[0]); // -> be careful about the whitespaces
printf("%c\n",ch);
printf("%d\n",number);
printf("%s\n",string);
You dont need to use spaces or \n to enter your input.

Resources