Inputting, Searching and Deleting String in an Array in C - 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

Related

Defining size for string using a variable not working properly in for loop in C

I'm trying to reverse the string input entered by user, the problem here is in function *rev, when I use size = strlen(STR); to get the length of the string and pass it into the size of the revS[size] the program outputs some garbage value for reverse string! if I pass some value instead if size in revS[10] and run the program it works as expected. I Have checked the value of size as
printf("\nlength of string is: %d\n",size);
and it gives the correct value. I'm not getting where is it going wrong!
#include<stdio.h>
#include<string.h>
char *rev(char *);
int main()
{
char string[100];
printf("Enter the string to reverse: ");
scanf("%s", string);
printf("You entered string : %s\n Reversed string is: %s", string, rev(string));
}
char *rev(char *STR)
{
int size, i, j = 0;
size = strlen(STR);
printf("\nlength of string is: %d\n", size);
char revS[size];
for(i = size-1; i >= 0; i--)
{
revS[j] = STR[i];
j = j + 1;
}
revS[j] = '\0';
return (revS);
}
OUTPUT:
Enter the string to reverse: mahaveer
length of string is: 8
You entered string : mahaveer
Reversed string is: ╚²b
--------------------------------
Process exited after 28.7 seconds with return value 0
Press any key to continue . . .
The issue is that your reversed string is allocated on the stack rather than the heap. When your rev function returns, all of the variables in that scope will be garbage collected. You can use malloc() to allocate memory dynamically on the heap. Note that the caller is responsible for calling free() on the string to avoid a memory leak.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *rev(char *);
int main() {
char string[100];
printf("Enter the string to reverse: ");
scanf("%s", string);
char *r = rev(string);
printf("You entered string: %s\nReversed string is: %s\n", string, r);
free(r);
}
char *rev(char *str) {
int i, j;
int size = strlen(str);
char *rev = malloc(sizeof(*rev) * (size + 1));
for (i = size - 1, j = 0; i >= 0; i--, j++) {
rev[j] = str[i];
}
rev[size] = '\0';
return rev;
}
Note that this code is susceptible to buffer overflows.
You have tho major UBs here. First you allocate local storage array which is not available after the function return. The second one - the size is too small to accomodate the string plus terminating zero

Getting input from the command line?

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

2D array printing

So, I am creating a program that reads in a file called "Bankfile.txt" and the the first number "3" is to indicate how many account we are working with. The numbers "123" "467" and "499" are the bank account numbers and the numbers next to each is their original balances. In my code I am using a 2D array to scan them in. I think I have everything correct in scanning them in but when I run the program the account numbers are being printed very weird as seen here. Any ideas on why it is being printed like this?
Thank you!
#include <stdio.h>
int main(){
FILE* file;
file = fopen("bankfile.txt","r");
int accounts,b=1,w=2,d=3,u=4,i,j,accNum,origBal;
float interest = .0185;
float test;
float accountInfo[accNum][origBal];
fscanf(file, "%d", &accounts);
for(i = 0; i < accounts; i++)
{
fscanf(file, "%d", &accountInfo[i]);
for(j = 0; j < 1; j++)
{
fscanf(file, "%f", &accountInfo[i][j]);
printf("Account %d has a balance of $%.2f\n", accountInfo[i], accountInfo[i][j]);
}
}
system("pause");
return 0;
}
Ok what you have here is not a 2-dimensional array -- this is conceptually wrong. An account number only has one balance associated with it. So what you have is only a single dimension, but your data has several fields ... that's where you use a struct in C. Here's some example code that would produce the output you expect:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* data structure holding a bank account */
typedef struct account
{
int id;
double balance;
} account;
int main(void)
{
int cap = 1024; /* initial capacity of account array */
int count = 0; /* number of accounts */
char buf[1024]; /* buffer for a line of text */
char *tok; /* token from text line */
FILE *bankfile;
int i;
account *accounts = malloc(cap * sizeof(account));
bankfile = fopen("bankfile.txt", "r");
while (fgets(buf, 1024, bankfile))
{
int accId;
tok = strtok(buf, " \t\r\n");
if (!tok) continue;
accId = atoi(tok);
if (accId > 0)
{
/* first token in line was a positive integer */
tok = strtok(0, " \t\r\n");
if (tok)
{
/* there was a second token in the same line, then we found
* an account with a balance */
accounts[count].id = accId;
accounts[count].balance = atof(tok);
if (++count == cap)
{
cap *= 2;
accounts = realloc(accounts, cap * sizeof(account));
}
}
}
}
fclose(bankfile);
for (i = 0; i < count; ++i)
{
printf("Account %d has a balance of $%.2f\n",
accounts[i].id, accounts[i].balance);
}
free(accounts);
return 0;
}
This can be simplified by first reading the first line and then only allocating as many elements of account as needed.
of course, for production, add error checking to fopen() and malloc() and friends ...
First of all I think you don't understand the concept of two-dimensional arrays. When you have a 2D array (foo) and add two arrays into that it will look something like this.
int foo[][] = { {1,2,3} {4,5,6} };
And when you call foo[0] it will actually refer to the first array you added (i.e [1,2,3]) and foo[1] will refer to the second array. You should instead use two seperate arrays called accountNum and accountBal.
Finally you never give values to accNum or origBal which makes your 2D array an empty array. So you could instead dynamically allocate memory for them based on the accounts variable.
Keeping this in mind you should change your main logic to solve these issues.
fscanf(file, "%d", &accounts);
accountNum = malloc(sizeof(int) * accounts);
accountBal = malloc(sizeof(float) * accounts);
for(i = 0; i < accounts; i++) {
fscanf(file, "%d", &accountNum[i]);
fscanf(file, "%f", &accountBal[i]);
printf("Account %d has a balance of $%.2f\n", accountNum[i], accountBal[i]);
}
free(accountBal);
free(accountNum);

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

How do I make a string array in C

I am not very experienced in C. I am trying to have some code that works like this:
Declare array of strings;
Function that erases array of strings
and inserts a new set of strings (number unknown)
How can I do this? I know I can do const char *a[2]; but that requires entering an array size when I declare it. Can I make a variable for my string array that can support multiple sizes?
You can use pointers to pointers.
char **strings;
Here is how you would create it: (where <size> is the size of the array)
strings = malloc(sizeof(char*) * <size>);
Now setting/getting elements is pretty simple:
strings[0] = "hello";
printf("%s", strings[0]);
Just a warning, the memory is not already set to fully null strings. If you want all of the strings to be empty by default then use calloc() instead of malloc():
strings = calloc(sizeof(char*) , <size>);
You can control array size like this:
int size;
char *a[size];
printf("enter size");
scanf("%d",&size);
You have to use a char**, a pointer to pointer to char, to by able to capture a dynamic array of strings.
If you want 10 strings, you have to use:
char** strings = (char**)malloc(sizeof(char*)*10);
To store a string in the first element of the array, you have to use:
strings[0] = malloc(strlen("abcd")+1);
strpcy(strings[0], "abcd");
Here's a program that demonstrates the whole thing:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char string[200];
char** strings = NULL;
int numStrings = 0;
int n = 0;
int i = 0;
/* Read the number of strings */
do
{
printf("Enter the number of strings (0 or higher): ");
n = scanf("%d", &numStrings);
} while ( n != 1 || numStrings < 0 );
/* Eat up the remaining characters afte the integer */
fgets(string, 199, stdin);
if ( numStrings > 0 )
{
/* Read the strings */
strings = (char**)malloc(numStrings*sizeof(char*));
for ( i = 0; i != numStrings; ++i )
{
printf("Enter a string: ");
fgets(string, 199, stdin);
strings[i] = malloc(strlen(string)+1);
strcpy(strings[i], string);
}
/* Print the strings back */
for ( i = 0; i != numStrings; ++i )
{
printf("%s", strings[i]);
}
/* Now release the memory back to the system */
/* First the individual strings */
for ( i = 0; i != numStrings; ++i )
{
free(strings[i]);
}
/* Now the array */
free(strings);
}
return 0;
}

Resources