C Convert string to integer using arrays - c

I'm making a program where user enters grades (1 to 5) and then the grade gets added to array for later inspection. When user enters letter "s", the program closes. When ran my program crashes, why?
#include <stdio.h>
#include <stdlib.h>
int i;
int grade[50];
char *num[20];
int enter();
int enter()
{
for (i=0; i<10; i++) {
printf("\nEnter grade:\nPress [s] to close program\n");
scanf("%s",&num[i]);
if (strcmp(num[i],"s") == 0) {
break;
} else {
grade[i] = atoi(num[i]);
}
}
}
int main()
{
enter();
for (i=0; i<10; i++) {
printf("\n%d",grade[i]);
}
return 0;
}

remove ' * ' from num[20] declaration, as you are declaring 20 character string pointers, so reading and comparing values with num[i] will cause error.
Besides, you just nead a simple string to get the grade.

The reason why program crashed is that num is a pointer array, the element of num can not pointer to valid memory which used to store the string you inputed.
you can change char *num[10] to char num[10][12] and 'scanf("%s", &num[i])to scanf("%s", num[i]), and that everything will be OK.
Of course, you can use malloc to dynamic alloc memory for each element in num, like:
`for(i = 0; i < 10; i ++){
num[i] = (char*)malloc(sizeof(char) * 12);
}
`
Even thought, you must change scanf("%s", &num[i]) to scanf("%s", num[i]);
Finally, you can not forget to free the memory you just dynamic malloc.

Related

C program prints garbage characters

I have an assignment to write a program in C that functions similarly to the bash sed 's/oldstring/newstring/g' but only using stdio.h and string.h. We cannot use malloc s we have not yet covered it in class. The program has to continue to take user input until the user enters ^D. We're using GCC so I have it set up to use variable length arrays and I've managed to get the program to find and replace a single instance of oldstring in the user input. However, on occasion the program will output some garbage characters and I am not sure why. I assume it is a memory allocation error or the program is reading past where I want it to read. The code is below:
#include <stdio.h>
#include <string.h>
int isMatch(char * os, char * us){
int i;
char temp[strlen(os)];
for(i=0; i<strlen(us); i++){
int k=0;
for(int j=i; j<i+strlen(os); j++){
temp[k]=us[j];
k++;
}
if(strcmp(temp, os)==0){
return 1;
}
else{
return 0;
}
}
}
void replace(char * os, char * us, char * ns, int loc){
char out[strlen(us) - (strlen(os) - strlen(ns))];
int i;
for(i=0; i<loc; i++){
out[i]=us[i];
}
int k=0;
for(i=loc; i<loc+strlen(ns); i++){
out[i]=ns[k];
k++;
}
k=0;
for(i=loc+strlen(ns); i<strlen(us)-(strlen(os)-strlen(ns)); i++){
out[i]=us[loc+strlen(os)+k];
k++;
}
printf("%s\n", out);
}
int main(int argc, char * argv[]){
char input[100];
int i;
char c;
int match;
while(1){
if(scanf("%c", &c)==EOF){
break;
}
if((input[0]=c) != '\n'){
for(i=1; i<100; i++){
scanf("%c", &input[i]);
if(input[i]=='\n'){
break;
}
}
}
for(i=0; i<100; i++){
match = isMatch(argv[1], &input[i]);
if(match == 1){
replace(argv[1], input, argv[2], i);
}
if(input[i]=='\n'){
break;
}
}
}
}
I call the program with ./a.out aa b for example.
I then enter helaalo and the program spits out helblo which is correct. I then enter libraary and the program outputs librbry followed by some random characters on new lines. I then enter caar and the program outputs cbr followed by even more random letters on new lines. A screenshot of this behavior is included.
Since you can't use malloc, you can force to add terminating \0 for the end of input string and end of out string,
// input
for(i=1; i<100; i++){
scanf("%c", &input[i]);
if(input[i]=='\n'){
input[i] = '\0'; // add terminating \0 for input
break;
}
}
// out
for(i=loc+strlen(ns); i<strlen(us)-(strlen(os)-strlen(ns)); i++){
out[i]=us[loc+strlen(os)+k];
k++;
}
int len = strlen(us)-(strlen(os)-strlen(ns));
out[len] = '\0'; // for out termiante \0
printf("%s\n", out);
The problem is coming from your the way you are filling your input buffer. You don't add a \0 at the end of the string.
There is also an other "problem", when you declare you array out if you want a dynamic size you need to use a malloc. how you are declaring it will not have a dynamic size , the size of the array will be calculated at compilation time. Just to keep it in mind.

Scan String Input for each testcase in C

the objective of my question is very simple. The first input that I get from the user is n (number of test cases). For each test case, the program will scan a string input from the user. And each of these strings I will process separately.
The question here is how can I get string inputs and process them separately in C language??? The idea is similar to the dictionary concept where we can have many words which are individual arrays inside one big array.
The program I have written so far:
#include <stdio.h>
#define max 100
int main (){
int n; // number of testcases
char str [100];
scanf ("%d\n",&n);
for (int i =0;i <n;i++){
scanf ("%s",&str [i]);
}
getchar ();
return 0;
}
Can someone suggest what should be done?
The input should be something like this:
Input 1:
3
Shoe
Horse
House
Input 2:
2
Flower
Bee
here 3 and 2 are the values of n, the number of test cases.
First of all, Don't be confused between "string" in C++ , and "Character Array" in C.
Since your question is based on C language, I will be answering according to that...
#include <stdio.h>
int main (){
int n; // number of testcases
char str [100][100] ; // many words , as individual arrays inside one big array
scanf ("%d\n",&n);
for (int i =0;i <n;i++){
scanf ("%s",str[i]); // since you are taking string , not character
}
// Now if you want to access i'th word you can do like
for(int i = 0 ; i < n; i++)
printf("%s\n" , str[i]);
getchar ();
return 0;
}
Now here instead of using a two-dimensional array, you can also use a one-dimensional array and separate two words by spaces, and store each word's starting position in some another array. (which is lot of implementation).
First of all yours is not C program, as you can't declare variable inside FOR loop in C, secondly have created a prototype using Pointer to Pointer, storing character array in matrix style datastructure, here is the code :-
#include <stdio.h>
#include <stdlib.h>
#define max 100
int main (){
int n,i; // number of testcases
char str [100];
char **strArray;
scanf ("%d",&n);
strArray = (char **) malloc(n);
for (i =0;i <n;i++){
(strArray)[i] = (char *) malloc(sizeof(char)*100);
scanf ("%s",(strArray)[i]);
}
for (i =0;i <n;i++){
printf("%s\n",(strArray)[i]);
free((strArray)[i]);
}
getchar ();
return 0;
}
#include <stdio.h>
#define MAX 100 // poorly named
int n=0; // number of testcases
char** strs=0;
void releaseMemory() // don't forget to release memory when done
{
int counter; // a better name
if (strs != 0)
{
for (counter=0; counter<n; counter++)
{
if (strs[counter] != 0)
free(strs[counter]);
}
free(strs);
}
}
int main ()
{
int counter; // a better name
scanf("%d\n",&n);
strs = (char**) calloc(n,sizeof(char*));
if (strs == 0)
{
printf("outer allocation failed!")
return -1;
}
for (counter=0; counter<n; counter++)
{
strs[counter] = (char*) malloc(MAX*sizeof(char));
if (strs[counter] == 0)
{
printf("allocate buffer %d failed!",counter)
releaseMemory();
return -1;
}
scanf("%s",&strs[counter]); // better hope the input is less than MAX!!
// N.B. - this doesn't limit input to one word, use validation to handle that
}
getchar();
// do whatever you need to with the data
releaseMemory();
return 0;
}

scanf confusion with type error

I just make a program to guess some random pairs in an array,if guess right, delete this pair.
I met a problem that I can only type integer number.Everytime I tried to type like * ,the program will crash. I use a condition like:
if (scanf("%d",&temp)==1)
to try to fix my problem, but it really does'nt work.
here is my code and please give me some help:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int r[4]; //random
int s[8]; //store
char c[8]; //cover
int g[8]; //guess
int i;
int round=0;
int left = 4;
int point = 0;
int clear_index[2];
int temp;
// generate random number
for (i=0;i<4;i++)
{
r[i] = (rand()%10)+1;
s[i] = r[i];
s[i+4] = r[i];
}
// show the default number
printf("[show] ");
for (i=0;i<8;i++)
{
printf("%d ",s[i]);
c[i] = '*';
}
printf("\n");
while(left>0)
{
// print left
printf("[cover] ");
for (i=0;i<8;i++)
printf("%c ",c[i]);
printf("\n");
//guess
printf("[guess] ");
for(i=0;i<8;i++)
{
if (scanf("%d",&temp)==1)
g[i] = temp;
if (g[i] == s[i])
{
printf("v\n");
clear_index[point] = i;
point++;
}
}
if (point == 2)
{
for (i=0;i<2;i++)
c[clear_index[i]]=' ';
left-=1;
point = 0;
}
round+=1;
//left-=1;
}
printf("you won in %d round",round);
}
You get the segmentation fault, because, in case, you did not enter an integer, scanf will not return 1, and then, using g[i] will invoke undefined behavior.
FWIW, g is a local automatic array variable, and unless initialized explicitly, will have indeterminate value. Attempt to read the value will invoke the UB.
Solution:
Always initialize the local variables.
In case scanf() fails, you need to eat up the invalid input using some loop like while (getchar != '\n'); before you proceed to take the next input.
You are reading a number but the user can place a digit. To prevent this you can use the function atoi() from the library stdlib.h. It converts a string to a integer, if the integer is just number digits, it'll convert it to a integer. If it is a character it will return 0. So you just need to prevent the occurrence of a 0 after the atoi() function is called.

C - how to store multiple strings in an array

Wondering how store different strings in an array.
For example a user would input 'qwe' and the program would then store that in an array variable[0]. Entering another string would then store it as variable[1] and so on
int
main(int argc, char *argv[]) {
char variable[1000];
int i;
printf("enter a variable\n");
scanf("%s", variable);
for (i = 0; ??? ;i++) {
printf("The variable entered was: %s\n",variable[i]);
}
return 0;
Im new to C so I have no idea what im doing. but thats what I have came up with so far and was wondering if I could get some help with filling in the rest
Thanks!
You can use 2D array to store multiple strings. For 10 strings each of length 100
char variable[10][100];
printf("Enter Strings\n");
for (int i = 0; i < 10 ;i++)
scanf("%100s", variable[i]);
Better to use fgets to read string.
fgets(variable[i], sizeof(variable[i]), stdin);
You can also use dynamic memory allocation by using an array of pointers to char.
The most efficient way is to have an array of character pointers and allocate memory for them as needed:
char *strings[10];
int main(int ac, char *av[]) {
memset(strings, 0, 10 * sizeof(char *));
for (int i = 0; i < 10; i += 1) {
char ins[100];
scanf("%100s", ins);
strings[i] = malloc(strlen(ins) + 1);
if (strings[i]) {
strcpy(strings[i], ins);
}
}
}
variable[0] has just stored first letter of string. If you want to store multiple strings in an array you can use 2D array.
it has structure like
arr[3][100] = { "hello","world", "there"}
and you can access them as
printf("%s", arr[0]); one by one.
scanf returns number of successful readed parameters;
use 2D array for string-array
Never go out of bounds array
#include <stdio.h>
//Use defines or constants!
#define NUM_STRINGS 10
#define MAX_LENGTH_OFSTRING 1000
int main() {
char variable[NUM_STRINGS][MAX_LENGTH_OFSTRING +1 /*for '\0' Null Character */];
int i = 0;
printf("enter a variable\n");
while(scanf("%s", variable[i]) > 0){//if you print Ctrl+Z then program finish work. Do not write more than MAX_LENGTH_OFSTRING symbols
printf("The variable entered was: %s\n",variable[i]);
i++;
if(i >= NUM_STRINGS)
break;
}
return 0;
}

taking input from user

i tried to take input from user
input type is not determined(can be char or int)
i wanna take input and store in pointer array
while i doing that job forr each pointer i wanna take place from leap area
that is using malloc
but below code doesnot work why???
int main(void)
{
char *tutar[100][20],temp;
int i;
int n;
i=0;
while(temp!='x')
{
scanf("%c",&temp);
tutar[i]=malloc(sizeof(int));
tutar[i]=temp;
++i;
}
n =i;
for(i=0;i<=n;++i)
{
printf(" %c ",*tutar[i]);
}
printf("\n\n");
/*for(i=0;i<=n;++i)
{
printf("%d",atoi(*tutar[i]));
}
*/
}
note that;
this cite has problem when rewrite(edit) the previous mail
it is general problem or not
There are several problems in your code, including:
you declare tutar as a two-dimensional array of pointers to character, then use it as a one-dimensional array
tutar[i]=temp assigns the value of temp (a char) to tutar[i] (a pointer to char), effectively overwriting the pointer to the newly reserved memory block
you don't initialize temp, so it will have garbage value - occasionally it may have the value x, in which your loop will not execute
Here is an improved version (it is not tested, and I don't claim it to be perfect):
int main(void)
{
char *tutar[100], temp = 0;
int i = 0;
int n;
while(temp!='x')
{
scanf("%c",&temp);
tutar[i]=malloc(sizeof(char));
*tutar[i]=temp;
++i;
}
n =i;
for(i=0;i<=n;++i)
{
printf(" %c ",*tutar[i]);
}
printf("\n\n");
}
Note that unless you really need to allocate memory dynamically, you would be better off using a simple array of chars:
char tutar[100], ...
...
while(temp!='x')
{
scanf("%c",&temp);
tutar[i++]=temp;
}
...
For the sake of brevity, I incremented i within the assignment statement.

Resources