I wrote a code in C, which utilizes dynamic memory allocation but my input gets skipped second iteration onwards.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
int n;
printf("Enter the number of users :");
scanf("%d", &n);
// char **array = malloc(n * sizeof(char *));
char flag[4];
for(int i=0;i<n;i++) {
printf("Does user have middle name? (yes/no) :");
scanf("%s", flag);
if (strcmp("yes", flag)==0) {
char **array = malloc(3 * sizeof(char *));
for(int j=0;j<3;j++)
array[i] = (char *)malloc(9);
printf("First name :");
scanf("%s", array[0]);
printf("Middle name :");
scanf("%s", array[1]);
printf("Last name :");
scanf("%s", array[2]);
for(int i=0;i<3;i++)
free(array[i]);
free(array);
}
else {
char **array = malloc(2 * sizeof(char *));
for(int j=0;j<2;j++)
array[i] = (char *)malloc(9);
printf("First name :");
scanf("%s", array[0]);
printf("Last name :");
scanf("%s", array[1]);
for(int i=0;i<2;i++)
free(array[i]);
free(array);
}
}
}
Here, say I give n=3 and enter "yes". It inputs the first, middle, last name but then skips the next "Does it have a middle name". Why is this happening??
The problem is here:
for(int j=0;j<3;j++)
array[i] = (char *)malloc(9);
you want to use the index j, not i:
for(int j=0;j<3;j++)
array[j] = malloc(9); // Don't cast malloc
You are also shadowing i in the inner loop:
for(int i=0;i<n;i++) {
...
for(int i=0;i<3;i++)
Related
I am trying to change the sorting of a the arr list which could consist of zero, one, two as the inputted and stored values for arr. The stringreplace function is meant to shift every single element by one so the new sorting would be one, two, zero. I am trying to replace the elements with one another by using the strncpy function but I think it is a bit faulty, how could i fix this?
strncpy function
char stringreplace( char a[], int b){
for(int j = 0; j > b -1; j++){
strncpy(a[j], a[j+1], sizeof(a));}
for(int j = 0; j > b; j++){
printf("%s",a[j]);}
}
main function
int main()
{
char input[100];
char arr[100]= {0};
int number;
printf("Input the number of strings: ");
scanf("%d", &number);
for(int i= 0; i < number; i++){
printf("Input the number of strings: ");
scanf("%s", input);
arr[i] = input;
}
stringreplace(arr, number);
return 0;
}
You may consider allocating strings dynamically, assigning a pointer for each string into an array words, and then rotating each pointer in the array to the left.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void lrot_words(char *words[], int n);
int main(void)
{
char *p, word[100], *words[100];
int i, num_words;
printf("Enter the number of words: ");
scanf("%d", &num_words);
for(i = 0; i < num_words; i++){
printf("Enter a word: ");
scanf("%s", word);
if ((p = malloc(strlen(word) + 1)) == NULL) {
fprintf(stderr, "Error: malloc failed\n");
exit(EXIT_FAILURE);
}
words[i] = strcpy(p, word);
}
lrot_words(words, num_words);
for (i = 0; i < num_words; i++) {
printf("%s\n", words[i]);
}
return 0;
}
void lrot_words(char *words[], int n)
{
char *temp = words[0];
int i;
for (i = 0; i < n - 1; i++) {
words[i] = words[i+1];
}
words[i] = temp;
}
How can I fix this code in a way that it prints the words in the array? Moreover this is the right way to dynamically allocate memory for n words of max size 40?
int main() {
int n;
char *arr;
int i;
printf("Give me a number:");
scanf("%d", &n);
arr = malloc(n * 40);
for (i = 0; i < n; i++)
{
printf("Give me a word: ");
scanf("%s", &arr[i]);
}
for (i = 0; i < n; i++)
{
printf("%s", arr[i]); //< --problem here
}
return 0;
}
Your allocation is not the best, and printf argument arr[i] expects a char* but you pass it an int (a char if you'd like).
Here is how you should do it, with comments:
Live demo
#include <stdio.h>
#include <stdlib.h> //for malloc
int main(){
int n;
int i;
printf("Give me a number:");
scanf("%d", &n);
//declare a variable of pointer to pointer to char
//allocate memory for the array of pointers to char,
//each one capable of pointing to a char array
char **arr = malloc(n * sizeof *arr);
if(arr == NULL){ //check for allocation errors
perror("malloc");
return EXIT_FAILURE;
}
//allocate memory for each individual char array
for(i = 0; i < n; i++){
arr[i] = malloc(40); //char size is always 1 byte
if(arr == NULL){ //check for allocation errors
perror("malloc");
return EXIT_FAILURE;
}
}
for (i = 0; i < n; i++){
printf("Give me a word: ");
//limit the size of read input to 39 charaters to avoid overflow,
//a nul character will be added by scanf
scanf("%39s", arr[i]);
}
for (i = 0; i < n; i++){
printf("%s\n", arr[i]);
}
for(int i = 0; i < n; i++){ //free the memory for each char array
free(arr[i]);
}
free(arr); //free array of pointers
return 0;
}
You can also do this with less code using a pointer to array of 40 chars, this will simplify the memory allocation and deallocation:
Sample with comments:
Live demo
#include <stdio.h>
#include <stdlib.h> //for malloc
int main(){
int n;
int i;
printf("Give me a number:");
scanf("%d", &n);
//declare a pointer to array of chars and
//allocate memory for all the char arrays
char (*arr)[40] = malloc(n * sizeof *arr);
if(arr == NULL){ //check for allocation errors
perror("malloc");
return EXIT_FAILURE;
}
for (i = 0; i < n; i++){
printf("Give me a word: ");
scanf("%39s", arr[i]);
}
for (i = 0; i < n; i++){
printf("%s\n", arr[i]);
}
free(arr); //free allocated memory
return 0;
}
This:
for(i=0;i<n;i++){
printf("Give me a word: ");
scanf("%s",&arr[i]);
}
is probably not what you want.
You probably want this instead:
for(i=0; i<n; i++){
printf("Give me a word: ");
scanf("%s", arr + i*40);
}
then later:
for(i=0; i<n; i++){
printf("%s", arr + i*40);
}
Remember that a string in C is just an array of characters.
Thus when defining char *arr, you are creating a single string. Had you done char **arr it would have been an array of strings, which is what you want.
However, I find that allocating/freeing arrays of arrays on the heap to be rather inconvenient, and prefer 'flattening' them into a single array.
This is exactly what you were doing with arr = malloc(n*40), but then later you treated this array of characters as an array of strings when you did this:
for(i=0; i<n; i++){
printf("Give me a word: ");
scanf("%s", &arr[i]);
}
Note that this is actually perfectly legal (scanf wanted a char* and you gave it one), but it's a logical error since you are giving it the n-th character when you wanted to give it the n-th array.
And oh yes, don't forget to free(arr) later.
#include<stdio.h>
#include<stdlib.h>
#define MSIZE 10
int main()
{
int Size, gen, i, j;
printf("Enter number of generations\t");
scanf("%d", &gen);
printf("\nEnter size of the matrix (max size is %d and min is 2)\t", MSIZE);
scanf("%d", &Size);
if (Size > MSIZE) {
printf("\nSize should not be more than %d", MSIZE);
return 1;
}
if (Size < 2) {
printf("\nSize should not be less than 2");
return 1;
}
char **m = (char**) calloc(Size, sizeof(char*));
for (i=0; i<Size; i++)
{
m[i] = (char*) calloc(Size, sizeof(char));
}
printf("Enter matrix of first generation\n");
for (i=0; i<Size; i++) {
for (j=0; j<Size; j++) {
scanf("%c", &m[i][j]);
/*to make sure*/
printf("%c ", m[i][j]);
}
printf("\n\n");
}
}
This is the first part of my program which should be about the death game for Conway. I think, the problem is in the input function, because if I fill it inside the program by myself (not by input) it will be printed right.
I think, the problem is in the input function, because if I fill it
inside the program by myself (not by input) it will be printed right.
You need a space before "%c" in scanf() to consume a previous newline/enter:
for (i=0; i<Size; i++) {
for (j=0; j<Size; j++) {
scanf(" %c", &m[i][j]);
/*to make sure*/
printf("%c ", m[i][j]);
}
printf("\n\n");
}
When you hit enter on the previous scanf(), a newline is placed in the input buffer. Adding a space in front of %c tells scanf() to skip that newline (and other whitespace).
The goal of my code is to have the user, put in any amount of students as an integer and then have the program ask over and over to set a name too every integer (student)
I've been trying so many different things and I've been working on this without using any outside help for hours but I just couldn't figure this out. (if its something obvious, please don't get supermad, I'm only a beginner)
#include <cs50.h>
#include <string.h>
#include <stdio.h>
int main (void)
{
printf("How many students are there? ");
int amount = atoi(GetString());
printf("amount = %i\n", amount);
char *names[amount];
for(int i = 0; i < amount; i++)
{
printf("Enter the ellement #%d :", i +1);
scanf("%s", names[i]);
}
for (int i = 0; i == 0;)
{
printf("Acces student: ");
string search = GetString();
int searchnr = atoi(search);
printf("Student #%d is %s\n", searchnr, names[searchnr]);
}
}
>
}
The obvious solution:
for (int i = 0; i < amount; i++) {
printf("Enter element #%d: ", i + 1);
names[i] = GetString();
}
As to the second loop: it's an infinite loop. What is the terminating condition? You need to put that into the condition of the for loop else it will never terminate.
If your intent is getting an infinite loop, then a more readable, less confusing, more idiomatic solution is
while (1) {
// ...
}
or
for (;;) {
// ...
}
You need to reserve space for those strings:
char *names[amount];
char s[100];
for(int i = 0; i < amount; i++)
{
printf("Enter the ellement #%d :", i +1);
scanf("%s", s);
names[i] = strdup(s);
}
or
char *names[amount];
char s[100];
size_t len;
for(int i = 0; i < amount; i++)
{
printf("Enter the ellement #%d :", i +1);
scanf("%s", s);
len = strlen(s);
names[i] = malloc(len + 1);
strcpy(names[i], s);
}
And this for loop:
for (int i = 0; i == 0;)
does nothing, what do you want to do? (if you want to loop forever you can use for(;;))
Using malloc
char temp[50];
for(int i = 0; i < amount; i++)
{
printf("Enter the ellement #%d :", i +1);
scanf("%s", temp);
names[i]=malloc(strlen(temp)+1);
strcpy(names[i],temp);
}
Using strdup
char temp[50];
for(int i = 0; i < amount; i++)
{
printf("Enter the ellement #%d :", i +1);
scanf("%s", temp);
names[i] = strdup(temp);
}
All your answers were great guys, but this was the final solution:
#include <cs50.h>
#include <string.h>
#include <stdio.h>
int main (void)
{
printf("How many students are there? ");
int amount = atoi(GetString());
char *names[amount];
for(int i = 0; i < amount; i++)
{
printf("Enter the ellement #%d :", i +1);
names[i + 1] = GetString();
}
for (int i = 0; i == 0;)
{
printf("Acces student: ");
int search = atoi(GetString());
printf("Student #%d is %s\n", search, names[search]);
}
}
and I know I have an infinite loop there, that was just temporary so I don't have to rerun the command all the time.
I am having a problem with this code:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(void)
{
int num=0;
printf("Enter number of entries: ");
scanf_s("%d", &num);
char **firstname=NULL;
char **lastname=NULL;
float *score=NULL;
int i;
firstname = malloc(num * (sizeof(char*)));
for (i = 0; i < num; i++)
{
firstname[i] = malloc(21);
}
lastname = malloc(num * (sizeof(char*)));
for (i = 0; i < num; i++)
{
lastname[i] = malloc(21);
}
score = ((float*)malloc(num* (sizeof(float))));
for (i = 1; i <= num; i++)
{
printf("Enter the first name of entry %d: \n", i);
scanf_s("%s", firstname[i], 21);
printf("Enter the last name of entry %d: \n", i);
scanf_s("%s", lastname[i], 21);
printf("Enter the score of entry %d: \n", i);
scanf_s("%f", score[i]);
}
for (i = 0; i < num; ++i)
{
printf("%s, %s, %f", firstname[i], lastname[i], score[i]);
}
return 0;
}
I have edited the code with the suggested changes, and now it prints random characters and a random value for the first and last name, as well as the score. the code also crashes if there is more than one iteration of input (after asking for the score of the first entry, it crashes before asking for the first name of the second entry.)