Getting input from the command line? - c

I want to store each of the 5 book names in the array and print them out. But what am I doing wrong here ?
The output prints out the last entry 5 times.
#include <stdio.h>
int main(int argc, const char * argv[])
{
char * books[5];
char currentBook[1024];
for(int i = 0; i < 5; i++)
{
printf("Enter book:\n");
gets(currentBook);
books[i] = currentBook;
}
for(int i = 0; i <5; i ++)
{
printf("Book #%d: %s\n", i, books[i]);
}
}

Given your declarations
char * books[5];
char currentBook[1024];
, this code ...
books[i] = currentBook;
... assigns books[i] to be a pointer to the beginning of array currentBook. You do that multiple times for various i, resulting in an array of pointers all pointing to the same array. When you later print the string to which each of those points, it is of course the same string.
You could approach the problem by using strdup() to make a copy of the input buffer instead of assigning each element of books to point to the same thing.

The problem is,your pointers will be pointing to the same string currentbook.
use strdup() instead to duplicate the strings:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, const char * argv[])
{
char *books[5];
char currentBook[1024];
for (int i = 0; i < 5; i++)
{
printf("Enter book:\n");
fgets(currentBook, sizeof(currentBook), stdin);
books[i] = strdup(currentBook);
}
for (int i = 0; i < 5; i++)
{
printf("Book #%d: %s\n", i, books[i]);
free(books[i]);
}
}

I want to store each of the 5 book names in the array
Then you need to define a suitable array.
Assuming you want to store 5 names, each with a maximum length of 42 characters, you need to define an array of 5 elements each being an array of 42 + 1 characters.
That is define a 2D-array of chars like this
char books [5][42 + 1]; /* Define one more char then you need to store the
`0`-terminator char ending each C "string". */
And use it like this
for(int i = 0; i < 5; i++)
{
printf("Enter book:\n");
fgets(books[i], 42 + 1, stdin);
}
On why to not use gets() you might like to read here: Why is the gets function so dangerous that it should not be used?
More on the concept of 0-terminated strings here: https://en.wikipedia.org/wiki/Null-terminated_string

Related

Inputting, Searching and Deleting String in an Array in C

Is it possible to input a string into any place in a two dimensional array?
char courseName[8][50] = {NULL};
printf("Enter your second course: ");
scanf("%[^\n]s", courseName[2]);
printf("Enter your fourth course: ");
scanf(" %[^\n]s", courseName[4]);
for(int i = 1; i < 9; i++)
{
printf("Name of the Courses in courseName[i][50] is %s\n", courseName[i]);
}
or delete a string inside the array by typing the name of the string?
char deleteCourse[50];
printf("Enter the course name to delete the course");
scanf(" %[^\n]s", deleteCourse);
for(int i = 1; i < 9; i++)
{
if(deleteCourse == courseName[i])
{
courseName[i] = {NULL};
}
printf("Your edited courses: %s\n", courseName[i]);
}
The best way to go about this would be to use pointers since you could simply strcpy to your destination of choice using pointer arithmetic. I'm not going to explain pointers here, I'm just going to show you a path you might take to do what you want to do.
What I'm about to show you is bare bones code that you can apply and modify according to your needs. It by no means takes all possible error cases into account.
Place an input string into destination of choice
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
/* Variables */
char **courseName;
int i;
/* Allocate memory to make courseName look like: courseName[4][100] */
/* I assume the memory allocated properly, but you need to check that */
courseName = malloc(sizeof(char*) * 4);
for(i = 0; i < 4; i++){
courseName[i] = malloc(100);
}
/* Copy string to your destination of choice using pointer arithmatic */
strcpy(courseName[2] + 50, "word");
/* Printing at different locations to show results */
printf("index [1][0] = %s\n", courseName[1]);
printf("index [2][0] = %s\n", courseName[2]);
printf("index [2][50] = %s\n", courseName[2] + 50);
printf("index [2][51] = %s\n", courseName[2] + 51);
return 0;
}
Output:
index [1][0] =
index [2][0] =
index [2][50] = word
index [2][51] = ord
Deleting a string from within a two dimensional array
Note: the code below does assume that word is at index [i][0] where i is the array in which the word is found. Since you don't specify exactly what you need, I'm assuming, from reading your question, that this should be ok. Nonetheless, you can modify according to your needs.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
/* Variables */
char **courseName, deleteWord[10], *result;
int i, arrayNum;
/* Allocate memory to make courseName look like: courseName[4][100] */
courseName = malloc(sizeof(char*) * 4);
for(i = 0; i < 4; i++){
courseName[i] = malloc(100);
}
/* Place a word into the array at a random location for the sake of the example */
strcpy(courseName[2], "word");
printf("index [2][0] = %s\n", courseName[2]);
/* The worrd we want to delete (can be a user input if you want) */
strcpy(deleteWord, "word");
/* Loop through the different arrays */
for(i = 0; i < 4; i++){
if( (result = strstr(courseName[i], deleteWord)) != NULL ){ /* use strstr() see if the word want to delete exists */
arrayNum = i; /* Get the array that the word is in (in this case courseName[2]) */
}
}
/* Empty the array at the location where the word is */
memset(courseName[arrayNum], 0, strlen(deleteWord));
/* "word" is deleted */
printf("index [2][0] = %s\n", courseName[2]);
/* but "sss" still exists */
printf("index [2][4] = %s\n", courseName[2] + 4);
return 0;
}
Output:
index [2][0] = wordsss
index [2][0] =
index [2][4] = sss

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;
}

Integer from pointer warning

I have I problem. I get 2 warnings from console, but I dont know what's wrong with my code. Can you have look?
Program suppose to show lines with at least 11 characters and 4 numbers
#include <stdio.h>
#include <ctype.h>
int main()
{
char line[200];
printf("Enter a string: \n");
while(fgets(line, sizeof(line),stdin))
{
int numberAlpha = 0;
int numberDigit = 0;
if(isalpha(line)) numberAlpha++;
else if(isdigit(line)) numberDigit++;
if(numberAlpha+numberDigit>10 && numberDigit>3) printf("%s \n", line);
}
return 0;
}
Both isalpha() and isdigit() takes an int, not a char *, as argument.
In your code, by passing the array name as the argument, you're essentially passing a char * (array name decays to the pointer to the first element when used as function argument), so, you're getting the warning.
You need to loop over the individual elements of line and pass them to the functions.
That said, just a suggestion, for hosted environment, int main() should be int main(void) to conform to the standard.
isalpha and isdigit are supposed to test if a char taken as int (a char can be safely converted to an int) is the encoding of an alphanumeric or digit character. You pass a char array, not an individual char. You need to test each char of the string you got, so you need a loop as:
for (int i=0; i<strlen(line); i++) {
if (isalpha(line[i])) numberAlpha++;
...
}
It is better to compute the length once:
int length = strlen(line);
for (int i=0; i<length; i++) {
...
}
You may also use a pointer to move along the string:
for (char *ptr = line; *ptr!=`\0`; ptr++) {
if (isalpha(*ptr)) ...
...
}
isalpha() and isdigit() functions take an int. But you are passing a char* i.e. the array line gets converted into a pointer to its first element (see: What is array decaying?). That's what the compiler complains about. You need to loop over line to find the number of digits and alphabets in it.
Also note that fgets() will read in the newline character if line has space. So, you need to trim it out before counting.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main(void)
{
char line[200];
printf("Enter a string: \n");
while(fgets(line, sizeof(line),stdin))
{
int numberAlpha = 0;
int numberDigit = 0;
line[strcspn(line, "\n")] = 0; // Remove the trailing newline, if any.
for (size_t i = 0; line[i]; i++) {
if(isalpha((unsigned char)line[i])) numberAlpha++;
else if((unsigned char)isdigit(line[i])) numberDigit++;
}
printf("alpha: %d, digits:%d \n", numberAlpha, numberDigit);
}
return 0;
}
Ok, i got something like this:
#include <stdio.h>
#include <ctype.h>
int main()
{
char line[200];
printf("Enter a string: \n");
while(fgets(line, sizeof(line),stdin))
{
int numberAlpha = 0;
int numberDigit = 0;
int i;
for(i=0; i<strlen(line); i++){
if(isalpha(line[i])) numberAlpha++;
else if(isdigit(line[i])) numberDigit++;
}
if(numberAlpha+numberDigit>10 && numberDigit>3) printf("%s \n", line);
}
return 0;
}
Now the question is, if it is passible to make it first accepts data and then display only those line which follows the if statment. Now it shows line just after input it.

Pointer error when trying to use "strcpy" in C to copy char elements from one array to another

What I am trying to do is check if the word entered by the user has first five alphabetical letters and if it has, I need to copy those letters to another array.But it gives me an error saying "passing argument 1 of strcpy makes pointer from integer without cast[enabled by default]".
char s1[100];
char a1[100];
char alpha[5]={'a','b','c','d','e'};
int i,j,k=0;
printf("Enter a word");
fgets(s1,100,stdin);
for(i=0;i<strlen(s1);i++)
{
for(j=0;j<5;j++)
{
if(s1[i]==alpha[j])
{
strcpy(a1[k],s1[i]);
k++;
}
}
}
Need help to figure out what is wrong with this
strcpy has two input parameters char *. You can't use it for two characters. If you want to copy one character from one array to another then you need to use = operator as a1[k] = s1[i]
You only need one loop:
Replace char by char:
for(i = 0; i < strlen(s1); i++)
{
a1[i] = s1[i];
}
Or, use strcpy like this: strcpy(a1, s1);
Answering your comment:
I tried a1[k]= s1[i] but it displays some vague characters for a1 ex-: if s1 is "abc" , a1 displays as "abc!"
C strings need to be null terminated.
Try doing this:
char s1[100] = {0};
char a1[100] = {0};
Small example:
#include <string.h>
#include <stdio.h>
int main()
{
char s1[100] = {0};
char a1[100] = {0};
int i,j,k=0;
printf("Enter a word: ");
fgets(s1,100,stdin);
for(i = 0; i < strlen(s1); i++)
{
a1[i] = s1[i];
}
printf("a1 now contains: %s", a1);
return 0;
}

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;
}

Resources