How can I take this values to an array? - arrays

I am trying to take this input from terminal.
ARRAY [1,2,3,4,5,6]
and pass the numbers to an array like this.
else if (strncmp(input, "CONSTRUCT", 9) == 0) {
printf("CONSTRUCT\n");
// CONSTRUCT [value1,value2,value3,...,valueN]
int i = 0;
char *token;
char *str = strdup(input);
char **array = str_split(str, '[');
char **array2 = str_split(array[1], ']');
char **array3 = str_split(array2[0], ',');
int array4[100];
for (i = 0; i < 100; i++){
array4[i] = atoi(array3[i]);
}
for (i = 0; i < 100; i++){
printf("%d\n", array4[i]);
}
for (i = 0; i < 100; i++){
root = insert(root, array4[i]);
}
printf("\n");
}

here you simply run off the end of an array
char** array3 = str_split(array2[0], ',');
int array4[100];
for (i = 0; i < 100; i++)
{
array4[i] = atoi(array3[i]);
}
array3 is dynamically sized to number of numbers + 1, but you try to access 100 entries
you placed a null entry at the end of the list, use that
int count = 0;
for (i = 0; i < 100; i++)
{
if (array3[i] == NULL)
break;
count++;
array4[i] = atoi(array3[i]);
}
for (i = 0; i < count; i++)
{
printf("%d\n", array4[i]);
}
for (i = 0; i < count; i++)
{
root = insert(root, array4[i]);
}
I saw your comment about the space. this code does not work with a space after 'CONSTRUCT', thats because
scanf("%s", input);
reads up to the first space - you want fgets.

Related

Run-Time Check Failure #2 - Stack around the variable 'chars' was corrupted

char* putNum(Node* head)
{
char* str;
int size = 0;
int index = 0;
int lastNum, count = 0;
Node* temp = head->left;
lastNum = temp->info;
while (lastNum != 0)
{
lastNum = lastNum / 10;
count++;
}
if (head->info < 0)
{
size = abs(head->info) - 1;
size *= 5 + count;
str = (char*)malloc(sizeof(char) * size);
str[0] = '-';
index++;
}
else
{
size = head->info - 1;
size *= 5 + count;
str = (char*)malloc(sizeof(char) * size);
}
for (int i = 0; i < abs(head->info); i++)
{
char chars[5];
itoa(temp->info, chars, 10);
for (int j = 0; j < strlen(chars); j++)
{
str[index++] = chars[j];
}
temp = temp->left;
}
return str;
}
hi im learing c in visual studio and im tring to make a function that take a doubly linked list with a long number and put the number in a string. the error pops in the last '}' of the function.

Checking if an array contains all the elements

I wrote a Code that reads from a txt.file stores it into an array , remove the spaces then print them out.
I want to add another functionality. This time is to check if the user provided the right input file.
I want to compare the array reds with the array stringcard and see if the array red contains all the elements of the array stringcard.
I have been searching on the internet for a while but I don't know how to solve this problem.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define max 13
#define stringlength 8
const char *stringcard[] = {
"REDA",
"RED2",
"RED3",
"RED4",
"RED5",
"RED6",
"RED7",
"RED8",
"RED9",
"RED10",
"REDJ",
"REDQ",
"REDK",
};
char * removechar(char str[], int ch) {
char * cpos = str;
while ((cpos = strchr(cpos, ch))) {
strcpy(cpos, cpos + 1);
}
return str;
}
int main(int argc, char ** argv) {
char * reds[max];
int i;
FILE * file = argc > 1 ? fopen(argv[1], "r") : stdin;
if (file == NULL)
return 1;
if (argc != 2) {
printf("[ERR]");
return 0;
}
for (i = 0; i < max; i++) {
reds[i] = malloc(stringlength);
fgets(reds[i], stringlength, file);
}
for (i = 0; i < max; i++) {
printf("%s", reds[i]);
}
// removes spaces
for (i = 0; i < max; i++) {
removechar(reds[i], ' ');
}
for (i = 0; i < max; i++) {
printf("%s", reds[i]);
}
int success = 1;
size_t size = sizeof(stringcard)/sizeof(stringcard[0]);
size_t size2 = sizeof(reds)/sizeof(reds[0]);
if(size == size2)
{
for(int i = 0; i<size;i++)
{
if(strcmp(stringcard[i], reds[i]) != 0){
success = 0;
printf("nope");
break;
}
}
}
return 0;
}
Input:
RED A
RED 2
RED 3
RED 4
RED 5
RED 6
RED 7
RED 8
RED 9
RED 10
RED J
RED Q
RED K
This is prefaced by my top comments.
This should work for cards in any order:
size_t size = sizeof(stringcard) / sizeof(stringcard[0]);
size_t size2 = sizeof(reds) / sizeof(reds[0]);
int allmatch = 0;
if (size == size2) {
allmatch = 1;
for (int i = 0; i < size; ++i) {
int curmatch = 0;
const char *curcard = &stringcard[i];
for (int j = 0; j < size; ++j) {
if (strcmp(curcard, reds[j]) == 0) {
curmatch = 1;
break;
}
}
if (! curmatch) {
allmatch = 0;
break;
}
}
}
printf("RESULT: %s\n",allmatch ? "MATCH" : "NOMATCH");
UPDATE:
if we know reds is sorted compare the result of strcmp with -1 or 1 rather than 0 depending on the order of the sorted elements. If stringcard is sorted of course exchange the roles
Okay, if we assume stringcard is always sorted [or we choose to pre-sort it], we can add an early escape to the inner loop that can save a small amount of time for the failed case:
size_t size = sizeof(stringcard) / sizeof(stringcard[0]);
size_t size2 = sizeof(reds) / sizeof(reds[0]);
int allmatch = 0;
if (size == size2) {
allmatch = 1;
for (int i = 0; i < size; ++i) {
int curmatch = 0;
char *redcard = reds[i];
for (int j = 0; j < size; ++j) {
int cmpflg = strcmp(redcard,stringcard[j]);
if (cmpflg == 0) {
curmatch = 1;
break;
}
if (cmpflg > 0)
break;
}
if (! curmatch) {
allmatch = 0;
break;
}
}
}
printf("RESULT: %s\n",allmatch ? "MATCH" : "NOMATCH");
Always try to use functions when possible.
int all_match(const char **table1, const char **table2, size_t t1size, size_t t2size)
{
for(size_t t1index = 0; t1index < t1size; t1index++)
{
int match = 0;
for(size_t t2index = 0; t2index < t2size; t2index++)
{
match = match || !strcmp(table1[t1index], table2[t2index]);
if(match) break;
}
if(!match) return 0;
}
return 1;
}
Given your other array is defined similarly, say inputArray, and both arrays are sorted before executing the following, then you could use code similar to: (including number of elements
//Assumes both arrays are sorted before executing the following
char success = 1;
size_t size = sizeof(stringcard)/sizeof(stringcard[0]);
size_t size2 = sizeof(inputArray)/sizeof(inputArray[0]);
if(size == size2)
{
for(int i = 0; i<size;i++)
{
if(strcmp(stringcard[i], inputArray[i]) != 0)
{
success = 0;
break;
}
}
{
else
{
success = 0;
}
//Proceed according to the value of success,
...

Passing a string array to a function to be altered

so currently I am running a program to generate a bundle of files at random, then have them connect to each other, and create a maze like game.
I'm trying to build an array of the file paths to pass to a function so it can be generated then the array can be worked on some more by the calling function. What's happening is that is generating the array but leaving the first element(filepath[0]) blank thus seg. faulting on me. But when I set a breakpoint, all other sections of the array are fine, just not the first element. It's been about 9 months since I wrote and C and I'm unsure where my pointer hiccup is coming from, thank you all in advanced
Here is the code so far
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <stdbool.h>
void create_files(char (*filepath[7]));
int main(){
time_t t;
char *filepath[7];
srand((unsigned) time(&t));
int i = 0;
for (i = 0; i < 7; i++)
filepath[i] = malloc(60);
create_files(filepath);
for (i = 0; i < 7; i++)
free(filepath[i]);
return 0;
}
void create_files(char (*filepath[7])){
int i = 0, pid = getpid(),q = 0,random, r=7;
char procid[20];
sprintf(procid, "%d", pid);
char directory[80] = "./dringb.rooms.";
strcat(directory,procid);
int newdir = mkdir(directory, 0777);
for (q = 0; q < 7; q++)
filepath[q] = directory;
char *bigrooms[10] ={"/Bridge.txt","/Gate.txt","/Hallway.txt",
"/Dungeon.txt","/Galley.txt","/Throne.txt","/Boss.txt", "/Lab.txt",
"/Torture.txt", "/Courtyard.txt"};
bool redflag = false;
char *rooms[7];
q = 0;
while (q != 7){ //grabs the rooms at random from the set of bigrooms
random = rand()%10;
for(i = 0; i < 7; i++){
if (rooms[i] == bigrooms[random])
redflag = true;
}
if (redflag == false){
rooms[q] = bigrooms[random];
redflag = false;
q++;
}
else
redflag = false;
}
char **dest = (char **)malloc(r * sizeof(char *));
for (i=0; i<r; i++)
dest[i] = (char *)malloc(8 * sizeof(rooms)); //allocates each room a new space
for (i = 0; i < 7; i++){
strcat(dest[i], directory);
strcat(dest[i],rooms[i]);
filepath[i] = dest[i]; //creates directory path for each room.txt
}
int usedrooms[4];
for (i = 0; i < 7; i++){
FILE *f = fopen(filepath[i], "w");
fputs("Roomname: ", f);
fputs(rooms[i],f);
fputs("\n",f);
fclose(f);
}
for (i = 0; i < 7; i++){
FILE *f = fopen(filepath[i], "a+");
for (q = 0; q < 4; q++)
usedrooms[q] = 100;
int roomrand, q = 0, z = 0, connrooms = 3;
bool greenflag = true, retry = false;
roomrand = rand() %2;
if (roomrand == 1)
connrooms = 4;
while (q != connrooms){ //prevents from having a connection to same room
do{
retry = false;
roomrand = rand() % 7;
for(z = 0; z < 4; z++){
if (roomrand == usedrooms[z])
retry = true;
}
}while(roomrand == i || retry == true); //prevents from having a connection to same room
bool found = false;
char buffer[100];
rewind(f);
while(fscanf(f,"%s", buffer) == 1){
if (strcmp(buffer,rooms[roomrand]) == 0)//prevents a double connecting room from being added
greenflag = false;
}
if(greenflag == true){
usedrooms[q] = roomrand;
fputs("Connecting Room: ", f);
fputs(rooms[roomrand],f);
fputs("\n",f);
}
fclose(f);
greenflag = true;
found = false;
FILE *f2 = fopen(filepath[roomrand],"a+");
rewind(f2);
while(fscanf(f2,"%s", buffer) == 1){
if (strcmp(buffer,rooms[i]) == 0) //prevents a double connecting room from being added
found = true;
}
if (found == false){
fputs("Connecting Room: ",f2);
fputs(rooms[i],f2);
fputs("\n",f2);
}
fclose(f2);
fopen(filepath[i],"a+");
found = false;
q++;
}
q = 0;
fclose(f);
}
int usedroomtype[7];
int roomrand;
for (i = 0; i < 7; i++)
usedroomtype[i] = 100;
for (i = 0; i < 7;i++){
do{
redflag = false;
roomrand = rand() % 7;
for (q = 0; q < 7; q++)
if (roomrand == usedroomtype[q])
redflag = true;
} while (redflag == true);
usedroomtype[i] = roomrand;
FILE *fp = fopen(filepath[roomrand], "a+");
if (i == 0)
fputs("Room Type: Start Room", fp);
else if (i == 6)
fputs("Room Type: End Room",fp);
else
fputs ("Room Type: Mid Room",fp);
fclose(fp);
}
}
The array is being passed correctly. The problem is that data is getting corrupted.
for (q = 0; q < 7; q++)
filepath[q] = directory;
This is invalid. It should be strcpy(filepath[q], directory); It's okay to set for example char *temp = filepath[q], because temp was not allocated. But filepath[q] is already allocated. Use strcpy to to change it value.
Later there is a similar error
char **dest = (char **)malloc(r * sizeof(char *));
for (i=0; i<r; i++)
dest[i] = (char *)malloc(8 * sizeof(rooms));
for (i = 0; i < 7; i++){
strcat(dest[i], directory);
strcat(dest[i],rooms[i]);
filepath[i] = dest[i]; //creates directory path for each room.txt
}
Two things. First, dest is not initialized. Always start with strcpy with uninitialized string, then use strcat. Second, use strcpy to change the value of filepath[i] as explained earlier. dest is actually not needed. You could just copy directly to filepath
for (i = 0; i < 7; i++)
{
strcpy(filepath[i], directory);
strcat(filepath[i], rooms[i]);
}
As mentioned in comments, allocation for filepath should be larger. directory is max 80 bytes, room is max 10 bytes, so filepath should be max 90 bytes.
for (i = 0; i < 7; i++)
filepath[i] = malloc(90);
Also some values are not initialized, example char *rooms[7];
Elsewhere:
int pid = getpid();
char procid[20];
sprintf(procid, "%d", pid);
char directory[80] = "./dringb.rooms.";
strcat(directory,procid);
You are already using sprintf, you can simplify this as follows:
sprintf(directory, "./dringb.rooms.%d", getpid());
Example:
int main()
{
time_t t;
srand((unsigned) time(&t));
char *filepath[7];
int i = 0;
for (i = 0; i < 7; i++)
filepath[i] = malloc(90);
create_files(filepath);
for (i = 0; i < 7; i++)
printf("%s\n", filepath[i]);
for (i = 0; i < 7; i++)
free(filepath[i]);
return 0;
}
void create_files(char *filepath[7])
{
int i = 0, random;
char directory[80];
sprintf(directory, "./dringb.rooms.%d", getpid());
//mkdir(directory);
mkdir(directory, 0777);
int q;
for (q = 0; q < 7; q++) strcpy(filepath[q], directory);
char *bigrooms[20] ={"/Bridge.txt","/Gate.txt","/Hallway.txt","/Dungeon.txt","/Galley.txt","/Throne.txt","/Boss.txt", "/Lab.txt","/Torture.txt", "/Courtyard.txt"};
bool redflag = false;
char *rooms[7];
for (i = 0; i < 7; i++) rooms[i] = 0;
q = 0;
while (q != 7)
{
//grabs the rooms at random from the set of bigrooms
random = rand()%10;
for(i = 0; i < 7; i++)
{
if (rooms[i] == bigrooms[random])
redflag = true;
}
if (redflag == false)
{
rooms[q] = bigrooms[random];
redflag = false;
q++;
}
else
redflag = false;
}
for (i = 0; i < 7; i++)
{
strcpy(filepath[i], directory);
strcat(filepath[i], rooms[i]);
}
int usedrooms[4];
for (i = 0; i < 7; i++)
{
FILE *f = fopen(filepath[i], "w");
fputs("Roomname: ", f);
fputs(rooms[i],f);
fputs("\n",f);
fclose(f);
}
for (i = 0; i < 7; i++)
{
FILE *f = fopen(filepath[i], "a+");
for (q = 0; q < 4; q++)
usedrooms[q] = 100;
int roomrand, q = 0, z = 0, connrooms = 3;
bool greenflag = true, retry = false;
roomrand = rand() %2;
if (roomrand == 1)
connrooms = 4;
while (q != connrooms)
{ //prevents from having a connection to same room
do
{
retry = false;
roomrand = rand() % 7;
for(z = 0; z < 4; z++)
{
if (roomrand == usedrooms[z])
retry = true;
}
}
while(roomrand == i || retry == true); //prevents from having a connection to same room
bool found = false;
char buffer[100];
rewind(f);
while(fscanf(f,"%s", buffer) == 1)
{
if (strcmp(buffer,rooms[roomrand]) == 0)//prevents a double connecting room from being added
greenflag = false;
}
if(greenflag == true)
{
usedrooms[q] = roomrand;
fputs("Connecting Room: ", f);
fputs(rooms[roomrand],f);
fputs("\n",f);
}
fclose(f);
greenflag = true;
found = false;
FILE *f2 = fopen(filepath[roomrand],"a+");
rewind(f2);
while(fscanf(f2,"%s", buffer) == 1)
{
if (strcmp(buffer,rooms[i]) == 0) //prevents a double connecting room from being added
found = true;
}
if (found == false)
{
fputs("Connecting Room: ",f2);
fputs(rooms[i],f2);
fputs("\n",f2);
}
fclose(f2);
fopen(filepath[i],"a+");
found = false;
q++;
}
q = 0;
fclose(f);
}
int usedroomtype[7];
int roomrand;
for (i = 0; i < 7; i++)
usedroomtype[i] = 100;
for (i = 0; i < 7; i++)
{
do
{
redflag = false;
roomrand = rand() % 7;
for (q = 0; q < 7; q++)
if (roomrand == usedroomtype[q])
redflag = true;
}
while (redflag == true);
usedroomtype[i] = roomrand;
FILE *fp = fopen(filepath[roomrand], "a+");
if (i == 0)
fputs("Room Type: Start Room", fp);
else if (i == 6)
fputs("Room Type: End Room",fp);
else
fputs ("Room Type: Mid Room",fp);
fclose(fp);
}
}

C program to find substring in string

So I may be attacking this the wrong way; I was learning a bit of Javascript and wrote a program that will find a string contained in another string and store the matches in an array (sorry if that didn't make too much sense, seeing my C program should help). I tried to translate my program to C, but it doesn't work; I think my issue is data types:
int main () {
char text[58];
strcpy(text, "I am James, James the Great, a pretty cool guy named James");
char store[16];
char name[6] = "James";
for (int i = 0; i <= 16; i++) {
if (text[i] == 'J') {
for (int k = i; k < i + 6; k++) {
store[k] = text[i];
}
}
}
int a = sizeof(store) / sizeof(store[0]);
for (int b = 0; b < a; b++) {
/* This should print out the values stored in the store array */
printf("%d", store[b]);
}
return 0;
}
My expected result would be something like:
JamesJamesJames
Instead I get:
10000747474747474-6374747474
So I'm assuming it's doing exactly what I told it to do, just not storing the letters into the array as letters, a bit confusing. Is there a better way to do this?
This is the javascript code I was trying to translate:
var text = "I am James, James the Great, a pretty cool guy named James";
var myName = "James";
var hits =[];
for (i = 0; i < text.length; i++) {
if (text[i] === "J") {
for (var j = i; j < i + myName.length ; j++) {
hits.push(text[j]);
}
}
}
if (hits.length === 0) {
console.log("Your name wasn't found!");
} else{
console.log(hits);
}
You are going to break store[] with this line
for (int k = i; k < i + 6; k++) {
because you are writing to the same index as you found the text in text[]. You also loop one too many times (6)
int ind = 0;
for (int k = 0; k < 5; k++) {
store[ind++] = text[i+k];
}
Then your next statement doesn't tell you anything about the data you collected
int a = sizeof(store) / sizeof(store[0]);
Just remove it, and print ind characters from store[].
You made following mistakes.
for (int i = 0; i <= 16; i++)
You iterate by '16' but this isn't proper length of text.
for (int k = i; k < i + 6; k++)
So you iterate by "i, i+1, i+2, i+3, i+4, i+5, i+6" here is 7 chars, "James" have 6.
store[k] = text[i];
You aren't changing "i" value so text[i] always return 'J'. It's better to use savePoistion variable so do I in the following code.
int a = sizeof(store) / sizeof(store[0]);
for (int b = 0; b < a; b++) {
/* This should print out the values stored in the store array */
printf("%d", store[b]);
}
I have no idea what are you trying to do here. It's really unnecessary.
printf("%d", store[b]);
"%d" means that you are printing integers so don't be surprised that your output was numbers. Just simply printf("%s\n", store);
This should look like this
int main () {
char text[58];
strcpy(text, "I am James, James the Great, a pretty cool guy named James");
char store[20];
int len = strlen(text);
int savePosition = 0;
int i, k;
for (i = 0; i < len; i++) {
if (text[i] == 'J') {
for ( k = i; k < i + 5; k++) {
store[savePosition] = text[k];
++savePosition;
}
}
}
store[savePosition] = '\0';
printf("%s\n", store);
return 0;
}
int main (void) {
char text[] = "I am James, James the Great, a pretty cool guy named James";
char name[] = "James";
char store[16] = {0};
int store_index = 0;
for (int i = 0; i < strlen(text); i++) {
if (text[i] == 'J') {
for (int k = i; k < i + strlen(name); k++) {
store[store_index++] = text[k];
}
}
}
if(strlen(store)==0) {
printf("Your name wasn't found!\n");
} else {
printf("%s\n", store);
}
return 0;
}
rewrite version.
int main (void) {
char text[] = "I am James, James the Great, a pretty cool guy named James";
char name[] = "James";
char store[sizeof(text)];
char *p = strstr(text, name);
if(p == NULL) {
printf("Your name wasn't found!\n");
} else {
int len = strlen(name);
int index = 0;
do {
memcpy(store + index, name, len);
index += len;
p = strstr(p + len, name);
} while(p != NULL);
store[index] = 0;
printf("%s\n", store);
}
return 0;
}

Anagram Solver, array[26] not working correctly

I've nearly finished my anagram solver program where I input two strings and get the result of whether they are anagrams of each other. For this example i'm using 'Payment received' and 'Every cent paid me'.
The problem i'm getting is when I output the letterCount arrays, letterCount1 is incorrect (it doesn't think there is a character 'd' but there is.) but letterCount2 is correct.
Can anyone see a problem with this because i'm completely baffled?
#include <stdio.h>
#include <string.h>
int checkAnagram(char string1[], char string2[])
{
int i;
int count = 0, count2 = 0;
int letterCount1[26] = {0};
int letterCount2[26] = {0};
for(i = 0; i < strlen(string1); i++)
{
if(!isspace(string1[i]))
{
string1[i] = tolower(string1[i]);
count++;
}
}
for(i = 0; i < strlen(string2); i++)
{
if(!isspace(string2[i]))
{
string2[i] = tolower(string2[i]);
count2++;
}
}
if(count == count2)
{
for(i = 0; i < count; i++)
{
if(string1[i] >='a' && string1[i] <= 'z')
{
letterCount1[string1[i] - 'a'] ++;
}
if(string2[i] >='a' && string2[i] <= 'z')
{
letterCount2[string2[i] - 'a'] ++;
}
}
printf("%s\n", string1);
for(i = 0; i < 26; i++)
{
printf("%d ", letterCount1[i]);
printf("%d ", letterCount2[i]);
}
}
}
main()
{
char string1[100];
char string2[100];
gets(string1);
gets(string2);
if(checkAnagram(string1, string2) == 1)
{
printf("%s", "Yes");
} else
{
printf("%s", "No");
}
}
That's because your count holds the count of non-space characters, but you keep the strings with the spaces.
For example, the string "hello world" has 11 characters, but if you run it through the loops your count will be 10 (you don't count the space). However, when you later go over the strings and count the appearance of each letter, you will go over the first 10 characters, therefore completely ignoring the last character - a 'd'.
To fix it, you need to go over all characters of the string, and only count the alphanumeric ones.
I fixed it for you:
#include <stdio.h>
#include <string.h>
int checkAnagram(char string1[], char string2[])
{
int i;
int count = 0, count2 = 0;
int letterCount1[26] = {0};
int letterCount2[26] = {0};
int len1 = strlen(string1);
int len2 = strlen(string2);
for(i = 0; i < len1; i++)
{
if(!isspace(string1[i]))
{
string1[i] = tolower(string1[i]);
count++;
}
}
for(i = 0; i < len2; i++)
{
if(!isspace(string2[i]))
{
string2[i] = tolower(string2[i]);
count2++;
}
}
if(count == count2)
{
for (i=0; i<len1; i++)
if (!isspace(string1[i]))
letterCount1[string1[i]-'a']++;
for (i=0; i<len2; i++)
if (!isspace(string2[i]))
letterCount2[string2[i]-'a']++;
int flag = 1;
for(i = 0; flag && i < 26; i++)
if (letterCount1[i] != letterCount2[i])
flag = 0;
return flag;
}
return 0;
}
main()
{
char string1[100];
char string2[100];
gets(string1);
gets(string2);
if(checkAnagram(string1, string2) == 1)
{
printf("%s", "Yes");
} else
{
printf("%s", "No");
}
}
First, don't calculate an string's length inside a loop. I extracted them into len1 and len2 variables.
Second, your loop was wrong! You shouldn't go up to count, you should go up to that string's length.
Third, you didn't return anything from checkAnagram function.

Resources