Adding strings to 2D array in C - c

I'm trying to write a program that looks for the first empty space in a 2D array and adds a custom string to that space. I have tried some things that i found on the internet but none seem to work or match my specific scenario. This is it:
#include <stdio.h>
#include <string.h>
int tags[10] = {1,2,3,4,5};
char owners[10][10] = {"per1", "per2", "per3", "per4", "per5"};
int tagAdd;
char ownerAdd;
int i;
int addBool;
int j;
int len;
int main()
{
printf("Enter the tag ID you want to add: ");
scanf("%d", &tagAdd);
printf("Enter the tag owners name: ");
scanf("%d", &ownerAdd);
len = strlen(ownerAdd);
while (i<10)
{
if (tags[i] == 0)
{
tags[i] = tagAdd;
owners[i][len] = ownerAdd; //This is the part I can't figure out
addBool = 1;
}
if (addBool == 1)
{
break;
}
i++;
}
i = 0;
addBool = 0;
len = 0;
while (i<10)
{
printf("tag[%d]", tags[i]);
len = strlen(owners[i]);
printf(" is owned by ");
while (j < len)
{
printf("%c", owners[i][j]);
j++;
}
printf("\n\r");
i++;
j = 0;
}
}

You cannot do this:
char ownerAdd;
scanf("%d", &ownerAdd);
len = strlen(ownerAdd);
You are passing the incorrect types. ownerAdd is a single char, scanf
expects with %d a pointer to int, you are passing a pointer to char and if
scanf converts the value, it will overflow. And strlen expects a char*
which points to a valid string (0-terminated). You are doing all this wrong.
This would be correct:
char ownerAdd[100];
scanf("%99s", ownerAdd);
len = strlen(ownerAdd);
And for replacing a value:
owners[i][len] = ownerAdd; //This is the part I can't figure out
is also wrong, because owners[i] is a char[10], you have to do:
strncpy(owners[i], ownerAdd, sizeof owners[i]);
owners[i][sizeof(owners[i]) - 1] = 0;
to copy the string.
The next error is that you don't initialize i and do (the first loop)
while (i<10)
{
...
}
this is going to fail. Same thing with j, it is uninitialized.

Related

How can I duplicate a letter in a string?

I want to write a program where it duplicates every letter in a given string.
For example, if the input is abc then the output would be aabbcc.
How can I do this?
Here is my code so far. It only copies the string:
#include <stdio.h>
int main () {
char str_in[100];
char str_out[200] = "";
int i;
printf("Enter a word: ");
scanf("%s", str_in);
for (i = 0; i < sizeof(str_in); i++) {
str_out[i] += str_in[i];
}
printf("Duplicated word: %s", str_out);
return 0;
}
For starters the destination character array should be at least two times larger than the source array.
The loop that performs the copying can look the following way
size_t j = 0;
for ( size_t i = 0; str_in[i] != '\0'; i++ )
{
str_out[j++] = str_in[i];
str_out[j++] = str_in[i];
}
str_out[j] = '\0';
This is one way to do what you want - since you know that the two indexes in str_out that you want to access correspond to the ith and i+1th positions of str_in:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 100
int main(void)
{
char str_in[SIZE];
char str_out[SIZE*2];
int i, len;
printf("Enter a word: ");
scanf("%s", str_in);
len = strlen(str_in);
for (i = 0; i < len; i++) {
str_out[i*2] = str_in[i];
str_out[i*2+1] = str_in[i];
}
str_out[i*2] = '\0';
printf("Duplicated word: %s\n", str_out);
return EXIT_SUCCESS;
}
You could also use another variable and update inside the loop as such:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 100
int main(void)
{
char str_in[SIZE];
char str_out[SIZE*2];
int i, j, len;
printf("Enter a word: ");
scanf("%s", str_in);
len = strlen(str_in);
for (i = 0, j = 0; i < len; i++, j += 2) {
str_out[j] = str_in[i];
str_out[j+1] = str_in[i];
}
str_out[j] = '\0';
printf("Duplicated word: %s\n", str_out);
return EXIT_SUCCESS;
}
As a side note, it's best to #define your constants instead of having them in your code.
I would suggest only allocating the amount of memory you need:
char *str_out = malloc(strlen(str_in) + 1);
and then using another loop variable that counts by 2 each time so you have 2 times as much space for every character in your loop.
If you do that, you should also put + 1 next to the new loop variable to copy it to the current and next elements of the string, thereby duplicating the characters.
I would also advise you to use size_t for your loop variables to match the return of str_len.
Here I have implemented my suggestions:
size_t str_ctr;
size_t str_ctrx2;
size_t in_str_len = strlen(in_str)
/* ... */
for( str_ctrx2 = str_ctr = 0;
str_ctr < in_str_len;
str_ctr++, str_ctrx2 += 2 )
{
out_str[str_ctrx2] = in_str[str_ctr];
out_str[str_ctrx2 + 1] = in_str[str_ctr];
}
/* null-terminate the string */
out_str[str_ctrx2] = '\0';
I would also like to mention that you forget to null-terminate your string in your program. I have made a comment about that and have shown you how to do it above.
#include <stdio.h>
int main () {
char str_in[100];
char str_out[200] = "";
int i, j;
printf("Enter a word: ");
scanf("%s", str_in);
j=0;
for (i = 0; i < sizeof(str_in); i++) {
str_out[i] = str_in[j];
str_out[i+1] = str_in[j];
i++;
j++;
}
printf("Duplicated word: %s", str_out);
return 0;
}

Comparing elements between 2 strings

Hello, let's say I got 2 strings, "Today is a nice day" and "ao". I want to delete the chars of the 2nd string that appear in the 1st one.
This is my issue:
char c[20];
char p[10];
int i,j;
int l1,l2;
printf("Enter a string \n");
scanf("%s",cd);
printf("Enter another string \n");
scanf("%s",car);
len1 = strlen(cd);
len2 = strlen(car);
for (i=0;i<len1;i++){
for (j=0;j<len2;j++){
if (cd[i]==car[j]){
cd[i]="";
}
}
}
What I want is the 1st string to be like "Tdy is nice dy". So I empty the positions where the elements are the same to reposition it later.
Apparently "cd[i]==car[j]" can't be done on C, I got "Invalid conversion from 'const char*' to 'char'.
So i'm pretty much stuck. I'll thank any help.
1) This is a solution matching your algorithm as close as possible.
All what you need is an extra loop and to replace cd[i]=""; which cannot be compiled with cd[i]=0;. The error given by the compiler relates to expression cd[i]=""; cd[i] is a character type and you cannot assign string "" which has a type const char * to char variable. cd[i] is a character "" is a pointer.
The operation cd[i]=0; gives you want you wanted: I empty the positions where the elements are the same to reposition it later. It replaces the unwanted characters with 0.
#include <stdio.h>
#include <string.h>
int main()
{
char cd[] = "Today is a nice day";
char tmp[] = "Today is a nice day";
char car[] = "ao";
int i;
int j;
int k;
int len1 = strlen(cd);
int len2 = strlen(car);
for (i=0;i<len1;i++){
for (j=0;j<len2;j++){
if (cd[i] == car[j]){
cd[i]=0;
}
}
}
k = 0;
for (i=0; i<len1; i++)
{
if(cd[i] == 0)
{
}
else
{
tmp[k] = cd[i];
k++;
}
}
tmp[k] = 0; /* remember to terminate the tmp */
printf("%s\n", tmp);
strcpy(cd,tmp);
printf("%s\n", cd);
return 0;
}
OUTPUT:
Tdy is nice dy
Tdy is nice dy
Alternatively, instead of clearing unwanted character with 0 you could just skip it. This solution is given below:
#include <stdio.h>
#include <string.h>
int main()
{
char cd[] = "Today is a nice day";
char car[] = "ao";
int i;
int j;
int k = 0;
int skip = 0;
int len1 = strlen(cd);
int len2 = strlen(car);
for (i=0; i<len1; i++)
{
for (j=0; j<len2; j++)
{
if (cd[i] == car[j])
{
skip++; // make note that this character is not needed
}
}
if(skip == 0)
{
cd[k] = cd[i]; // copy the character
k++; // increase the position index
}
else
{
// skip the copy of charcter; clear the skip marker
skip = 0;
}
}
cd[k] = 0; // remember to terminate the new ck string!
printf("%s\n", cd);
return 0;
}
OUTPUT:
Tdy is nice dy

Element in First Index Doesn't Behave as the Rest

so I'm trying to do a very simple task. I need to write a function that gets an empty array of strings and its size and initialize it (for example "names={"dani", "gabi", "bobi"}, names is array of size 3 and each one hold a string that the user inputs). So first the user needs to put the size then I allocate the array and then I trying to get strings for the array each one for different address.
Now for some reason it works great for the rest of the array except for the one in the first index (arr[0]). I understand that because the "ENTER" is a char it gets it for the first string (when the user inputs the size)
But I don't want it to be like this and I'm trying to fix it for hours and I'm hopeless
#define _CRT_SECURE_NO_WARNINGS#define SIZE 21
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum { FAIL = 0, SUCCESS = 1 };
int init_arr(char ***arr, int *size);
int main()
{
int i, sizes = 0;
char **course = NULL;
init_arr(&course, &sizes);
for (i = 0; i< sizes; i++)
puts(course[i]);
free(course);
return 0;
}
int init_arr(char ***arr, int *size)
{
int i;
char* c;
printf("Enter the Number of--->:");
scanf("%d", size);
*arr = (char**)malloc((*size) * sizeof(char*));
if ((*arr) == NULL)
{
printf("Error");
return FAIL;
}
for (i = 0; i < (*size); i++)
{
c = (char*)calloc(SIZE, sizeof(char));
if (c == NULL)
{
printf("Error");
return FAIL;
}
printf("Enter Name %d-->:", i);
fgets(c, SIZE, stdin);
(*arr)[i] = c;
}
return SUCCESS;
}
getchar(); will do the work:
printf("Enter the Number of--->:");
scanf("%d", size);
getchar(); // to read newline character

String array prints out trash values

So I have an assignment where I should delete a character if it has duplicates in a string. Right now it does that but also prints out trash values at the end. Im not sure why it does that, so any help would be nice.
Also im not sure how I should print out the length of the new string.
This is my main.c file:
#include <stdio.h>
#include <string.h>
#include "functions.h"
int main() {
char string[256];
int length;
printf("Enter char array size of string(counting with backslash 0): \n");
/*
Example: The word aabc will get a size of 5.
a = 0
a = 1
b = 2
c = 3
/0 = 4
Total 5 slots to allocate */
scanf("%d", &length);
printf("Enter string you wish to remove duplicates from: \n");
for (int i = 0; i < length; i++)
{
scanf("%c", &string[i]);
}
deleteDuplicates(string, length);
//String output after removing duplicates. Prints out trash values!
for (int i = 0; i < length; i++) {
printf("%c", string[i]);
}
//Length of new string. The length is also wrong!
printf("\tLength: %d\n", length);
printf("\n\n");
getchar();
return 0;
}
The output from the printf("%c", string[i]); prints out trash values at the end of the string which is not correct.
The deleteDuplicates function looks like this in the functions.c file:
void deleteDuplicates(char string[], int length)
{
for (int i = 0; i < length; i++)
{
for (int j = i + 1; j < length;)
{
if (string[j] == string[i])
{
for (int k = j; k < length; k++)
{
string[k] = string[k + 1];
}
length--;
}
else
{
j++;
}
}
}
}
There is a more efficent and secure way to do the exercise:
#include <stdio.h>
#include <string.h>
void deleteDuplicates(char string[], int *length)
{
int p = 1; //current
int f = 0; //flag found
for (int i = 1; i < *length; i++)
{
f = 0;
for (int j = 0; j < i; j++)
{
if (string[j] == string[i])
{
f = 1;
break;
}
}
if (!f)
string[p++] = string[i];
}
string[p] = '\0';
*length = p;
}
int main() {
char aux[100] = "asdñkzzcvjhasdkljjh";
int l = strlen(aux);
deleteDuplicates(aux, &l);
printf("result: %s -> %d", aux, l);
}
You can see the results here:
http://codepad.org/wECjIonL
Or even a more refined way can be found here:
http://codepad.org/BXksElIG
Functions in C are pass by value by default, not pass by reference. So your deleteDuplicates function is not modifying the length in your main function. If you modify your function to pass by reference, your length will be modified.
Here's an example using your code.
The function call would be:
deleteDuplicates(string, &length);
The function would be:
void deleteDuplicates(char string[], int *length)
{
for (int i = 0; i < *length; i++)
{
for (int j = i + 1; j < *length;)
{
if (string[j] == string[i])
{
for (int k = j; k < *length; k++)
{
string[k] = string[k + 1];
}
*length--;
}
else
{
j++;
}
}
}
}
You can achieve an O(n) solution by hashing the characters in an array.
However, the other answers posted will help you solve your current problem in your code. I decided to show you a more efficient way to do this.
You can create a hash array like this:
int hashing[256] = {0};
Which sets all the values to be 0 in the array. Then you can check if the slot has a 0, which means that the character has not been visited. Everytime 0 is found, add the character to the string, and mark that slot as 1. This guarantees that no duplicate characters can be added, as they are only added if a 0 is found.
This is a common algorithm that is used everywhere, and it will help make your code more efficient.
Also it is better to use fgets for reading input from user, instead of scanf().
Here is some modified code I wrote a while ago which shows this idea of hashing:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define NUMCHAR 256
char *remove_dups(char *string);
int main(void) {
char string[NUMCHAR], temp;
char *result;
size_t len, i;
int ch;
printf("Enter char array size of string(counting with backslash 0): \n");
if (scanf("%zu", &len) != 1) {
printf("invalid length entered\n");
exit(EXIT_FAILURE);
}
ch = getchar();
while (ch != '\n' && ch != EOF);
if (len >= NUMCHAR) {
printf("Length specified is longer than buffer size of %d\n", NUMCHAR);
exit(EXIT_FAILURE);
}
printf("Enter string you wish to remove duplicates from: \n");
for (i = 0; i < len; i++) {
if (scanf("%c", &temp) != 1) {
printf("invalid character entered\n");
exit(EXIT_FAILURE);
}
if (isspace(temp)) {
break;
}
string[i] = temp;
}
string[i] = '\0';
printf("Original string: %s Length: %zu\n", string, strlen(string));
result = remove_dups(string);
printf("Duplicates removed: %s Length: %zu\n", result, strlen(result));
return 0;
}
char *remove_dups(char *str) {
int hash[NUMCHAR] = {0};
size_t count = 0, i;
char temp;
for (i = 0; str[i]; i++) {
temp = str[i];
if (hash[(unsigned char)temp] == 0) {
hash[(unsigned char)temp] = 1;
str[count++] = str[i];
}
}
str[count] = '\0';
return str;
}
Example input:
Enter char array size of string(counting with backslash 0):
20
Enter string you wish to remove duplicates from:
hellotherefriend
Output:
Original string: hellotherefriend Length: 16
Duplicates removed: helotrfind Length: 10

Code to Reverse String not clearing up previous values

I am doing this programming problem where I have reverse string of about 30 characters for 10 test cases.
My code is this:-
#include <stdio.h>
#include <string.h>
int main () {
int t;
scanf("%d",&t);
while (t--) {
char str[30];
scanf("%s",&str);
char revStr[30];
int len = strlen(str);
int i = 0;
int j = len-1;
while (i < len) {
revStr[i] = str[j];
i++; j--;
}
printf("%s\n",revStr);
}
return 0;
}
The output gets garbled up if the input string is larger than previous string.
For example,
if last-string had 6 characters, like rocket\0 and new-string, which is fun\0 has 3 characters, the output is funket\0.
char str[30];
scanf("%s",&str);
^ don't pass address of array
Just this would work -
scanf("%29s",str);
Try this:
int t;
scanf("%d", &t);
while (t--)
{
char str[30] = { 0 };
scanf("%s", &str);
char revStr[30] = { 0 };
int len = strlen(str);
int i = 0;
int j = len - 1;
while (i < len) {
revStr[i] = str[j];
i++; j--;
}
printf("%s\n", revStr);
}
You need to make two changes
Firstly change scanf("%s",&str); to
scanf("%s",str);
Secondly, after the while loop, you are not making the last element rev string \0. Add this line before the printf statement.
revStr[i] = '\0';
This should solve your problem.

Resources