Struct and a symbol array - c

can you help me?
i have a problem with char* station;
when i fill my gaps, everithing is alright, but when i am with printf("%d)Input its stations: ",i+1);. It's a problem, i mean: i enter chech-joch-chor-dsh-dsh but i need to enter chech joch chor dsh dsh(these are names of stations,it's an example).So it prints ONLY THE FIRST WORD, i dont why.. check this out please... (i understand that i need to free what i'have taken). Please, explain why it is so, why the first?.. give me a hint..
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
typedef struct info_bus_{
int number;
int begin;
int end;
char* stations;
int time_working;
}info_bus;
int main()
{
info_bus *b=NULL;
int i,n;
char buffer[128];
printf("How many buses u have: ");
scanf("%d",&n);
b=(info_bus *)malloc(n*sizeof(info_bus));
for(i=0;i<n;i++){
printf("Input the number of a bus: ");
scanf("%d",&(b+i)->number);
printf("%d)Input when it starts to work: ",i+1);
scanf("%d",&(b+i)->begin);
printf("%d)Input when it finishes to work: ",i+1);
scanf("%d",&(b+i)->end);
printf("%d)Input its stations: ",i+1);
scanf("%127s", buffer);
b[i].stations = (char*) malloc(strlen(buffer) + 1);
strcpy(b[i].stations, buffer);
printf("Input time working: ");
scanf("%d",&(b+i)->time_working);
}
for (i=0;i<n;i++){
printf("\n[%d].the number of a bus: %d",i+1,b->number);
printf("\n[%d]. Begin at: %d",i+1,b->begin);
printf("\n[%d]. Finishes at: %d",i+1,b->end);
printf("\n[%d]. Stations: %s",i+1,b->stations);
printf("\n[%d]. Time working: %d",i+1,b->time_working);
printf("\n");
}
return 0;
}
but when i use gets()
it is:

scanf("%127s", buffer);
stops reading after encountering a newline. If you want to be able to read multiple words then use fgets():
fgets(buffer, sizeof buffer, stdin);
Note: fgets() will also read the newline character if there's room. You can remove it if necessary:
buffer[strcspn(buffer, "\n")] = 0; /* to remove the newline */
Generally, avoid using scanf() even for other inputs. It's error prone. See: Why does everyone say not to use scanf? What should I use instead?
Also, the cast of malloc() is unncessary. See: What's wrong with casting malloc's return value?

Related

using malloc for char variable can not take input data character

I am trying to implement DMA for char variable. But I am unable to take input. I tried with all the possible cases I know:
//gets(ptr_name);
//scanf("%[^\n]", &ptr_name);
//fgets(ptr_name, name, stdin);
But I can't even enter input data for the character variable ptr_name. I want to take input as "string with space" as input value. How to solve this problem?
And then how to print the entered name in the screen?
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
int main()
{
char* ptr_name;
int name, i;
printf("Enter number of characters for Name: ");
scanf("%d",&name);
ptr_name = (char*)malloc(name);
printf("Enter name: ");
//gets(ptr_name);
//scanf("%[^\n]", &ptr_name);
//fgets(ptr_name, name, stdin);
printf("\n Your name is: ");
puts(ptr_name);
free(ptr_name);
return 0;
}
scanf("%d", ...) does not consume the enter so the next scanf() gets an empty string.
you can use getchar() to consume the enter.
Also, you need to allocate additional byte for the zero at the end of the string / string terminator. See the + 1 in malloc().
As for your questions, your commented scanf() had & before argument 2 which isn't expected (char ** vs. char *) but other than that it will allow spaces in strings. puts() will print the entered name, alternatively you can modify the above printf() to print the name, e.g: printf("\n Your name is: %s", ptr_name);
Lastly, please consult Specifying the maximum string length to scanf dynamically in C (like "%*s" in printf) for dynamically limiting the input size, avoiding buffer overflow.
DISCLAIMER: The following is only "make it work" version of the program above and is not intended for real life use without appropriately checking return codes and limiting the input size:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char* ptr_name;
int name, i;
printf("Enter number of characters for Name: ");
scanf("%d",&name);
getchar();
ptr_name = (char*)malloc(name + 1);
printf("Enter name: ");
scanf("%[^\n]", ptr_name);
printf("\n Your name is: ");
puts(ptr_name);
free(ptr_name);
return 0;
}
if you want to get input with spaces you need to use getline():
getline(&buffer,&size,stdin);
here an example:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char* ptr_name;
int len;
printf("Enter number of characters for Name: ");
scanf("%d",&len);
ptr_name = (char*)malloc(len);
printf("Enter name: ");
getline(&ptr_name, &len, stdin);
printf("\n Your name is: %s", ptr_name);
free(ptr_name);
return 0;
}

How can I put a user input value into strncpy?

So, I am trying to write an strncpy function. I want user to input the number of characters to be copied from source. I am doing something wrong, but I can't understand what. This is what I tried to do:
#include <stdio.h>
#include <string.h>
#define ARR_SIZE 20
int main() {
char string[ARR_SIZE];
int n, m;
char s1[4], s2[4], nstr[m];
printf("Enter the string:");
gets(string);
printf("The length of the string is: %ld\n", strlen(string));
strcpy(s1, s2);
printf("The original string is: %s\n", string);
printf("The copy of the original string is: %s\n", string);
printf("How many characters do you want to take from this string to create another string? Enter: \n");
scanf("%d", &n);
strncpy(nstr, s1, m);
printf("%s\n", nstr);
}
(On top I tried some strlen and strcpy functions.)
EDIT: I totally forgot to write what was the problem. Problem is I can't get the new string which is named nstr in my code. Even though I printed it out.
first of all, the whole code is just a bad practice.
Anyway, here is my take on your code which copies n characters of an input string to string_copy
#include <stdio.h>
#include <string.h>
#define ARR_SIZE 20
int main() {
char string[ARR_SIZE];
int n;
printf("Enter the string:");
gets(string);
printf("The length of the string is: %ld\n", strlen(string));
printf("The original string is: %s\n", string);
printf("How many characters do you want to take from this string to
create another string? Enter: \n");
scanf("%d", &n);
if(n > strlen(string)){
n = strlen(string);
printf("you are allowed to copy maximum of string length %d\n", n);
}
char string_copy[n];
strncpy(string_copy, string, n);
printf("%s\n", string_copy);
}
note that using deprecated functions such as gets() isn't safe. use scanf() or fgets() instead.
refer to why you shouldn't use gets()

unable to take two input strings in C on Ubuntu

I am unable to take two inputs strings simultaneously in C on Ubuntu. It shows the wrong output.
Simple program:
#include <stdio.h>
main()
{
char s1[20],char s2[20],printf("\nEnter job:");
scanf("%[^\n]s",s1);
printf("Enter hobby:");
scanf("%[^\n]s",s2);
}
Output:
Enter job:student
Enter hobby:
student
It does not allow the input of a second string. How can I overcome this bug?
If you want to allow embedded spaces, modify the scanf formats this way:
#include <stdio.h>
int main(void) {
char job[100], hobby[100];
printf("Enter job:");
scanf("%99[^\n]%*c", job);
printf("Enter hobby:");
scanf("%99[^\n]%*c", hobby);
printf("%s,%s", job, hobby);
return 0;
}
But be aware that empty lines will not be accepted by this scanf format. The linefeed will stay in the input stream, the second scanf will fail too and job and/or hobby will have indeterminate contents, letting printf invoke undefined behavior.
Is is much more reliable to use fgets() and strip the '\n'.
#include <stdio.h>
#include <string.h>
int main(void) {
char job[100], hobby[100];
printf("Enter job:");
if (!fgets(job, sizeof job, stdin))
return 1;
job[strcspn(job, "\n")] = '\0';
printf("Enter hobby:");
if (!fgets(hobby, sizeof hobby, stdin))
return 1;
hobby[strcspn(hobby, "\n")] = '\0';
printf("%s,%s", job, hobby);
return 0;
}

Program bypass first fgets

The problem is when it asks the user to enter the name of the band.The program bypass the first fgets, but executes the printf and not the fgets. I tried to handle this problem with if but again the same problem. Bypass the first fgets. I provide you an image also.
#include <stdio.h>
#include <stdlib.h>
struct cd
{
char band[100];
};
struct cd *music;
int main()
{
int n,i;
printf("Give how many albums you want: ");
scanf("%d",&n);
struct cd *music = malloc(sizeof(struct cd)*n);
for(i=0;i<n;i++)
{
printf("\nEnter Band: ");
fgets(music->band,sizeof(music->band),stdin);
music++;
}
for(i=n-1;i>=0;i--)
music--;
for(i=0;i<n;i++)
{
printf("\nBand: %s",music->band);
music++;
}
printf("\n\n");
return 0;
}
Scanf() treats '\n' as a character and since it is not in the format string, it leaves it there.
try this
char newline;
int n,i;
printf("Give how many albums you want: ");
scanf("%d%c",&n,&newline);
This will remove the '\n' from the stdin.
when you read with scanf() it reads everything leaving the following '\n' from the end
And Now when you try to read with fgets()it reads the'\n' character left by scanf
To solve this you can use fgetc(stdin); after your scanf so that it gets consume.

scanf is not waiting for input

I'm trying to find the bug here, but still don't get it.
I've been debugging and googling it and found some close topics, but there are only solutions which I don't need ATM, and I'm curious why this code is not working:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define BUFFER 256
int main()
{
int missionCode;
char *desc = (char*)malloc(sizeof(char)*BUFFER);
do {
printf("Please enter the mission code (or -1 for exit): ");
scanf("%d", &missionCode);
fflush(NULL);
if (missionCode==-1)
return 1;
} while (missionCode>10);
do {
printf("Please enter a string:\n");
scanf("%[^\n]s", desc); //it doesn't stop here!
fflush(NULL);
if (!strcmp("exit",desc))
return 1;
} while (strlen(desc)<20);
printf("your string:\n%s", desc);
return 0;
}
There's something wrong with the scanf\flushall in the second loop, but I don't find out what.
BTW, this is C ofcourse.
scanf("%d", &missionCode);
leaves the newline in the buffer, so
scanf("%[^\n]s", desc);
immediately finds one and stops. You can add a space
scanf(" %[^\n]s", desc);
to the format to skip initial whitespace.

Resources