Converting integer to string with atoi/sprintf - c

This is not my whole code I just sum it up to be easy to see. I have no problem to convert the string into an integer but I cannot convert the integer into a string.
The program just crashes. Here is the code. Look at the line with itoa.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define SIZEX 49
#define SIZEY 6
int main() {
size_t x, y;
char *a[50][7];
char name[50][100];
char surname[50][100];
char IN[50][100];
char YOB[50][100];
char usname[50][100];
char pass[50][100];
char totamount[50][100];
for (x = 0; x <= SIZEX; x++) {
a[x][0] = name[x];
a[x][1] = surname[x];
a[x][2] = IN[x];
a[x][3] = YOB[x];
a[x][4] = usname[x];
a[x][5] = totamount[x];
a[x][6] = pass[x];
}
printf("\nPlease enter the name of the new user\n");
scanf(" %s", a[0][0]);
printf("Please enter the surname of the new user\n");
scanf(" %s", a[0][1]);
printf("Please enter the Identity Number of the new user\n");
scanf(" %s", a[0][2]);
printf("Please enter the year of birth of the new user\n");
scanf(" %s", a[0][3]);
printf("Please enter the username of the new user\n");
scanf(" %s", a[0][4]);
strcpy(a[0][6], a[0][4]);
strrev(a[0][6]);
a[0][5] = "0";
int z;
z = atoi(a[0][5]);
z = z + strlen(a[0][4]) * 10;
itoa(z, a[0][5], 10);
//sprintf(a[0][5], "%d", z);
printf("%s\n", a[0][5]);
printf("%d\n", z);
return 0;
}

By doing this:
a[0][5]="0";
You are assigning to a[0][5] a pointer to a readonly memory containing string literal "0".
Here:
itoa( z, a[0][5],10 );
you are attempting to write there, giving you memory access violation.

Related

Proteincalculator with algebra

Im trying to make this protein-calculator (in C language) to work but it doesn't work:
#include <stdio.h>
#include <stdlib.h>
int main()
{
double proteinhalt[20];
double proteinmangdtot[20];
double kottfiskmengdtot;
printf("Enter proteinhalt / 100 gram: ");
fgets(proteinhalt, 20, stdin);
printf("Enter proteinmangd att konsumera idag (gram): ");
fgets(proteinmangdtot, 20, stdin);
kottfiskmengdtot = ((double)proteinmangdtot/(double)proteinhalt)*100;
printf("Du behöver %f gram.", kottfiskmengdtot);
}
The error is:
Line 13 error: pointer value used where a floating-point was expected
What is wrong?
Edit: In english:
#include <stdio.h>
#include <stdlib.h>
int main()
{
double proteinpercentage[20];
double proteinamounttot[20];
double meatfishamounttot;
printf("Enter proteinpercentage / 100 gram: ");
fgets(proteinpercentage, 20, stdin);
printf("Enter protein amount to consume today (gram): ");
fgets(proteinamounttot, 20, stdin);
meatfishamounttot = ((double)proteinamounttot/(double)proteinpercentage)*100;
printf("You need %f gram.", meatfishamounttot);
}
You have two errors.
fgets, expects a character array as argument, but you specify an array of doubles
at the assignment of meatfishamounttot, you cast an array of doubles to a double
Solution (simplified, no error checking):
char str[20];
double proteinpercentage;
double proteinamounttot;
double meatfishamounttot;
// read at most 20 characters from stdin
fgets(str, 20, stdin);
// convert the string to a double
proteinpercentage = strtod(str, NULL);
fgets(str, 20, stdin);
proteinamounttot = strtod(str, NULL);
meatfishamounttot = (proteinamounttot / proteinpercentage) * 100;
This is how the program should work:
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
int main()
{
char str[20];
double proteinpercentage;
double proteinamounttot;
double meatfishamounttot;
printf("Enter proteinpercentage / 100 gram: ");
fgets(str, 20, stdin);
proteinpercentage = strtod(str, NULL);
printf("Enter protein amount to consume today (gram): ");
fgets(str, 20, stdin);
proteinamounttot = strtod(str, NULL);
meatfishamounttot = (proteinamounttot / proteinpercentage) * 100;
printf("You need %f grams.", meatfishamounttot);
}

How to make code say 'invalid input' when a user enters a character or a string (Validate)

I'm new to c and i just wanted to know how to make my code say ' invalid input' if they decide to enter a character or gibberish.
My code is just a simple Celsius to Kelvin (i know very simple) and i just adds 273 to any inputted number. i tried to use isdidgit but it was unsuccessful.
My code;
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
int temp = 273;
int cel;
int cel2;
int choice;
switch (choice)
{
case 1:
printf("enter ce to conv to kel: ");
scanf("%ld", &cel);
cel2 = cel + temp;
printf("%d in Celsuis is: %d Kelvin \n", cel, cel2)
I accept all feedback / improvements,
thanks
~Neamus
Presently, your code has no way to recover from an invalid input. That is, if a user enters "a" when prompted, scanf() will never return because it will be waiting for a base-10 integer value.
What you will need to do is read the input as a C-string and process that:
char input[80];
do {
printf("enter ce to conv to kel: ");
scanf("%79[^\n]\n", input); // read until newline; toss newline
} while (input_is_bad(input)); // your function to validate input
cel = atoi(input); // atoi parses C-string, returning an int
cel2 = cel + temp;
printf("%d in Celsuis is: %d Kelvin \n", cel, cel2);
Inside your own input_is_bad() function, you can print a message stating that the input is not valid.
You can achieve this by using fgets and strtol. See the following code:
#include<stdio.h>
#include <stdlib.h>
int main()
{
int temp = 273;
int cel;
int cel2;
int choice;
int flag;
char *p, str[100];
printf("enter ce to conv to kel: ");
while (fgets(str, sizeof(str), stdin)) {
cel = strtol(str, &p, 10); //number of base 10
if (p == str || *p != '\n') {
printf("Please enter an integer: ");
}
else break; //if input is integer then break the loop
}
//do your calculations here
return 0;
}

updating string array inside a function in C

I define a string array in main function, and I want to update it inside another function as follows:
#include <stdio.h>
#define SIZE 15
void read_arrays(char *competitors[SIZE], float points[SIZE], int numOfCompetitors)
{
for (int cntr = 0; cntr < numOfCompetitors; cntr++)
{
printf("Enter the name of competitor %d", cntr+1);
scanf("%s", &*competitors[cntr]);
printf("Enter the point of competitor %d", cntr+1);
scanf("%f", &points[cntr]);
}
}
int main()
{
char *competitors[SIZE];
float points[SIZE];
int numOfCompetitors = 0;
while (numOfCompetitors > 15 || numOfCompetitors < 1)
{
printf("Enter the number of competitors: ");
scanf("%d", &numOfCompetitors);
if (numOfCompetitors > 15) printf("Number of competitors cannot be more than 15!\n");
}
read_arrays(&*competitors[SIZE], &points[SIZE], numOfCompetitors);
printf("%f", points[0]);
}
But I get the following error:
cc homework2.c -o homework2
homework2.c: In function ‘main’:
homework2.c:28:14: warning: passing argument 1 of ‘read_arrays’ from incompatible pointer type [-Wincompatible-pointer-types]
read_arrays(&*competitors[SIZE], &points[SIZE], numOfCompetitors);
^
homework2.c:5:6: note: expected ‘char **’ but argument is of type ‘char *’
void read_arrays(char *competitors[SIZE], float points[SIZE], int numOfCompetitors)
I want to assign the values in array of strings with scanf in a loop. How I can manage to do that?
You can just use the name of the variable when you pass it to the function, you also need to specify the size of the char matrix (~ array of strings).
So this: read_arrays(&*competitors[SIZE], &points[SIZE], numOfCompetitors);
Becomes: read_arrays(competitors, points, numOfCompetitors);
Full code:
#include <stdio.h>
#define SIZE 15
void read_arrays(char competitors[SIZE][30], float points[SIZE], int numOfCompetitors)
{
for (int cntr = 0; cntr < numOfCompetitors; cntr++)
{
printf("Enter the name of competitor %d", cntr+1);
// We read up to 29 characters => no overflow as the size is up to 30
scanf("%29s", competitors[cntr]);
printf("Enter the point of competitor %d", cntr+1);
scanf("%f", &points[cntr]);
}
}
int main()
{
char competitors[SIZE][30];
float points[SIZE];
int numOfCompetitors = 0;
while (numOfCompetitors > 15 || numOfCompetitors < 1)
{
printf("Enter the number of competitors: ");
scanf("%d", &numOfCompetitors);
if (numOfCompetitors > 15) printf("Number of competitors cannot be more than 15!\n");
}
read_arrays(competitors, points, numOfCompetitors);
printf("%s", competitors[0]);
printf("%s", competitors[1]);
printf("%f", points[0]);
}
As an alternative to Daniel Illescas you could just allocate space for each competitor that you input. Just be sure to free them later.
#include <stdio.h>
#define SIZE 15
void read_arrays(char *competitors[SIZE], float points[SIZE], int numOfCompetitors)
{
for (int cntr = 0; cntr < numOfCompetitors; cntr++)
{
competitors[cntr] = (char*)calloc(1, 32);
printf("Enter the name of competitor %d", cntr + 1);
scanf("%s", competitors[cntr]);
printf("Enter the point of competitor %d", cntr + 1);
scanf("%f", &points[cntr]);
}
}
int main()
{
char *competitors[SIZE];
float points[SIZE];
int numOfCompetitors = 0;
while (numOfCompetitors > 15 || numOfCompetitors < 1)
{
printf("Enter the number of competitors: ");
scanf("%d", &numOfCompetitors);
if (numOfCompetitors > 15) printf("Number of competitors cannot be more than 15!\n");
}
read_arrays(competitors, points, numOfCompetitors);
printf("%f", points[0]);
}

C Structure Declaration Issue

I am writing the following program for my Programming Fundamentals Class (C Programming). My IDE is giving me a compile error for the declaration of 'student' as referenced in the lines where user input is read. It is also giving me an error on ISO C standards for nested functions in the letter_grade function. Any help would greatly be appreciated.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define MAX 20
char letter_grade(float a, float b, float c);
int main(void)
{
char temp_name[MAX];
int count=0, last, temp;
struct student {
char f_name[MAX];
char l_name[MAX];
float test1;
float test2;
float test3;
};
printf("Please enter the student's last name (Enter ZZZ to exit): ");
gets(temp_name);
while (strncmp(temp_name, "ZZZ\0", 4))
{
strncpy(student[count].l_name, temp_name, MAX+1);
printf("Please enter the students first name: ");
scanf("%s", &student[count].f_name);
getchar();
printf("Enter the first test score: ");
scanf("%f", &student[count].test1);
printf("Enter the second test score: ");
scanf("%f", &student[count].test2);
printf("Enter the third test score: ");
scanf("%f", &student[count].test3);
printf("\nPlease enter the student's last name (Enter ZZZ to exit): ");
gets(temp_name);
count++;
}
last = count;
temp = last + 1;
printf("\t\t\tStudent Grade Report");
for (last;last>=0;last--){
printf("%s, ", student[last].l_name);
printf("%s ", student[last].f_name);
printf("\t\t Grade: %c\n\n ", letter_grade(student[last].test1, student[last].test2, student[last].test2));
// printf("Test Grade: %c\n", letter_grade(85,88,82));
return 0;
}
char letter_grade(float *a, float *b, float *c)
{
float sum = *a+*b+*c;
if (sum >= 270.0f)
return 'A';
if (sum>= 240.0f && sum <270.0f)
return 'B';
if (sum>= 210.0f && sum <240.0f)
return 'C';
if (sum>= 180.0f && sum <210.0f)
return 'D';
if (sum < 180.0f)
return 'F';
}
You nowhere declared an array or a pointer with name student. The name was not declared. Thus the code where you are refering the name like this statement
strncpy(student[count].l_name, temp_name, MAX+1);
^^^^^^^
is invalid.
What is "student"? Where is it declared?
You only declared type struct student but it is not the same as an object with name student.
Also in this loop
for (last;last>=0;last--){
printf("%s, ", student[last].l_name);
printf("%s ", student[last].f_name);
printf("\t\t Grade: %c\n\n ", letter_grade(student[last].test1, student[last].test2, student[last].test2));
there is absent the closing brace.
Applying all the comments and correcting other problems in the posted code there were many results in:
#include <stdio.h>
#include <string.h>
#define MAX_NAME_LEN (20)
#define MAX_STUDENTS (100)
// define the student struc
struct student
{
char f_name[ MAX_NAME_LEN ];
char l_name[ MAX_NAME_LEN ];
float test1;
float test2;
float test3;
};
char letter_grade(float a, float b, float c);
int main(void)
{
// define an array of 100 instances of the student struct
struct student students[ MAX_STUDENTS ];
printf("Please enter the student's last name (Enter ZZZ to exit): ");
int count=0;
while( count < MAX_STUDENTS && scanf( " %19s", students[count].l_name) && strcmp( students[count].l_name, "ZZZ" ) )
{
printf("Please enter the students first name: ");
scanf(" %19s", students[count].f_name);
printf("Enter the first test score: ");
scanf("%f", &students[count].test1);
printf("Enter the second test score: ");
scanf("%f", &students[count].test2);
printf("Enter the third test score: ");
scanf("%f", &students[count].test3);
count++;
printf("\nPlease enter the student's last name (Enter ZZZ to exit): ");
} // end while
printf("\t\t\tStudent Grade Report");
for ( ; count>=0; count--)
{
printf("%s, ", students[count].l_name);
printf("%s ", students[count].f_name);
printf("\t\t Grade: %c\n\n ",
letter_grade( students[count].test1,
students[count].test2,
students[count].test2));
} // end for
} // end function: main
char letter_grade(float a, float b, float c)
{
float sum = a+b+c;
char grade;
if( sum >= 270.f) grade = 'A';
else if (sum>= 240.0f) grade = 'B';
else if (sum>= 210.0f) grade = 'C';
else if (sum>= 180.0f) grade = 'D';
else grade = 'F';
return grade;
} // end function: letter_grade
You can compare the posted code to the above answer to spot where there were problems in the posted code.
Do not #include header files those contents are not used.
A passed value to a function does not become a pointer in the parameter list of the called function.
In any if then else sequence, there is no need to re-test for previously eliminated values
The posted code nested one function inside another, That is not valid C code, although can be allowed with the gcc compiler extension.
There is no need for a return statement from main() if the returned value is 0.
On any non void function, ALL paths through the code must lead to a return value; statement.
The posted code failed to declare any instance of the struct student structure. And certainly did not declare an array of those struct instances, as is needed when multiple students being processed.
The posted code (and this answer) will fail if any first or last name is greater than or equal to 20 characters.
This answer does not check for failures of the call to scanf() but for reliability, such checking for each must be performed. Similar to:
if( 1 != scanf( " %19s", students[count].l_name) )
{
perror( "scanf failed" );
exit( EXIT_FAILURE ); // `exit()` and `EXIT_FAILURE` found in stdlib.h
}
// implied else, scanf successful
The while() statement in the main() function is very 'busy' for clarity, the call to strcmp() could be extracted and placed in a following statement similar to:
while(...)
{
if( !strcmp( students[count].l_name, "ZZZ" ) {
{
break;
}
...
In general, never trust the input from a user. That is why the returned value (not the parameter value) from each call to scanf() needs to be checked.
As a simplification, rather than hardcoding the MAX LENGTH modifier in the calls to scanf() with a %s format specifier, can use the following changes:
#define MAX_NAME_LEN (19)
...
struct student
{
char f_name[ MAX_NAME_LEN+1 ];
char l_name[ MAX_NAME_LEN+1 ];
float test1;
float test2;
float test3;
};
....
&& scanf(" %" MAX_NAME_LEN "s", students[count].l_name) &&
....
scanf(" %" NAX_NAME_LEN "s", students[count].f_name);

Cannot output an array in C programming?

I cannot seem to output a string or an integer array correctly in C programming.
My issue, is that the strings are stored in the array, I just cannot get them OUT of the array and to the output.
When I manually enter the positions (like Array[0]), it properly outputs.
However, the final loop fails to output any of my array entries.
Why is this happening?
Thanks in advance for all replies!
Here is the code:
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include <string.h>
main (void)
{
int memory_start;
int memory_end;
int num_jobs;
printf("Enter the starting memory location to be used : ");
scanf("%d", &memory_start);
printf("\nEnter the ending memory location to be used : ");
scanf("%d", &memory_end);
printf("\nHow many jobs will be assigned to the memory locations? \n");
scanf("%d", &num_jobs);
int mem_size = memory_end - memory_start;
int mem_size_init = memory_end - memory_start;
char names[10][20];
int sizes[num_jobs];
int mem_st[10];
int mem_end[10];
int x;
int y;
int z;
int temp_size = 0;
int prev_temp_size;
char temp_name[20];
for(x=0; x<num_jobs; x++)
{
prev_temp_size = prev_temp_size + temp_size;
printf("\nEnter the size of the program (size > 0): ");
scanf("%d", &temp_size);
if( mem_size >= temp_size && temp_size > 0)
{
printf("\nEnter a program name (20 chars): %s", names[1]);
scanf("%s", &temp_name);
if(strlen(temp_name) <= 20)
{
strcpy(names[x], temp_name);
// names[x] = temp_name;
sizes[x] = temp_size;
mem_size = mem_size - temp_size;
mem_st[x] = prev_temp_size + memory_start;
mem_end[x] = temp_size + mem_st[x];
}
else
{
printf("\nProgram name is too long. Please re enter data.");
x--;
}
}
else
{
printf("\nMemory Size not supported (not enough space remaining).\nPlease re-enter data with a plausible memory request.");
printf("\nMemory size remaining: %d", mem_size);
x--;
}
}
printf("\nYour data is as follows: \n");
printf("\nYour initial memory size is: %d", mem_size_init);
printf("\nYour unused memory size is: %d", mem_size);
for(y=0; y<num_jobs; y++)
{
printf("Program: %s", names[y]);
printf("\n", names[y], " memory size is as follows: \n", "memory start: %d", mem_st[y], " memory end: %d", mem_end[y]);
}
}
Here is the corrected code:
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include <string.h>
main (void)
{
int memory_start;
int memory_end;
int num_jobs;
printf("Enter the starting memory location to be used : ");
scanf("%d", &memory_start);
printf("\nEnter the ending memory location to be used : ");
scanf("%d", &memory_end);
printf("\nHow many jobs will be assigned to the memory locations? ");
scanf("%d", &num_jobs);
int mem_size = memory_end - memory_start;
int mem_size_init = memory_end - memory_start;
char names[10][20];
int sizes[num_jobs];
int mem_st[10];
int mem_end[10];
int x;
int y;
int z;
int temp_size = 0;
int prev_temp_size;
char temp_name[20];
for(x=0; x<num_jobs; x++)
{
prev_temp_size = prev_temp_size + temp_size;
printf("\nEnter the size of the program (size > 0): ");
scanf("%d", &temp_size);
if( mem_size >= temp_size && temp_size > 0)
{
printf("\nEnter a program name (20 chars): ");
scanf("%s", temp_name);
getchar();
if(strlen(temp_name) <= 20)
{
strcpy(names[x], temp_name);
sizes[x] = temp_size;
mem_size = mem_size - temp_size;
mem_st[x] = prev_temp_size + memory_start;
mem_end[x] = temp_size + mem_st[x];
}
else
{
printf("\nProgram name is too long. Please re enter data.");
x--;
}
}
else
{
printf("\nMemory Size not supported (not enough space remaining).\nPlease re-enter data with a plausible memory request.");
printf("\nMemory size remaining: %d", mem_size);
x--;
}
}
printf("\nYour data is as follows: \n");
printf("\nYour initial memory size is: %d", mem_size_init);
printf("\nYour unused memory size is: %d\n", mem_size);
for(y=0; y<num_jobs; y++)
{
printf("\nProgram: %s\n", names[y]);
printf("\nmemory size is as follows:\nmemory start: %d memory end: %d\n", mem_st[y], mem_end[y]);
}
}
Apart from changes in formatting the output, major changes are:
Removed the & in scanf("%s", &temp_name); because, the name of an array already returns a reference to its first element.
Added a getchar(); after scanf("%s", temp_name); because after reading in a string an extra \n remains in the stream, which causes the next scanf to fail.
This:
printf("\n", names[y], " memory size is as follows: \n", "memory start: %d", mem_st[y], " memory end: %d", mem_end[y]);
is not how a format specifier is prepared, all variables need to be placed at the end, after a single format specifier string.
The last loop is the issue.
for(y=0; y<num_jobs; y++)
{
printf("Program: %s", names[y]);
printf("\n memory size is as follows: ");
printf("\n memory start: %d memory end: %d", mem_st[y], mem_end[y]);
}
In C, the variables are given at the end of the printf. Also you are printing names two times, which i guess you don't want.

Resources