Passing a string array to a function to be altered - c

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

Related

Is there something wrong with the Main or is it the GetGraph function?

double d = atof(argv[1]);
double diffPR = atof(argv[2]);
int maxIterations = atoi(argv[3]);
FILE *fp = fopen("collection.txt", "r");
char *urlList[MAX];
char tempStringOne[MAX];
for (int i = 0; fscanf(fp, "%s", tempStringOne) != EOF; i++)
{
urlList[i] = malloc(strlen(tempStringOne) + 1);
strcpy(urlList[i], tempStringOne);
}
fclose(fp);
** Graph urlGraph = GetGraph();
**
int numUrls = checkNumberUrls();
// for each URL in the collection (PR = 1/N)
double *PR = malloc(numUrls * sizeof(double));
for (int i = 0; i < numUrls; i++) {
PR[i] = 1.0 / numUrls;
}
while (iteration < maxIterations && diff >= diffPR) {
// calculate new PR values
int t = iteration;
// For each URL u in the collection PR(u,t+1) = (1-d)/N + d * sum(PR(v,t) / outDegree(v))
double *newPR = malloc(numUrls * sizeof(double));
for (int i = 0; i < numUrls; i++) {
double sum = 0;
for (int j = 0; j < numUrls; j++) {
if (isConnected(urlGraph, j, i)) {
sum += PR[j] / outDegree(urlGraph, j);
}
}
newPR[i] = (1 - d) / numUrls + d * sum;
}
// calculate diff
diff = 0;
for (int i = 0; i < numUrls; i++) {
diff += fabs(newPR[i] - PR[i]);
}
// update PR
for (int i = 0; i < numUrls; i++) {
PR[i] = newPR[i];
}
iteration++;
}
Graph GetGraph()
{
FILE *fp = fopen("collection.txt", "r");
char *urlList[MAX];
char tempStringOne[MAX];
for (int i = 0; fscanf(fp, "%s", tempStringOne) != EOF; i++)
{
urlList[i] = malloc(strlen(tempStringOne) + 1);
strcpy(urlList[i], tempStringOne);
}
fclose(fp);
int numUrls = checkNumberUrls();
Graph urlGraph = newGraph(numUrls);
for (int i = 0; i < numUrls; i++) {
char *url = urlList[i];
char *filename = malloc(strlen(url) + 5);
strcpy(filename, url);
strcat(filename, ".txt");
FILE *fp = fopen(filename, "r");
char tempStringTwo[MAX];
while (fscanf(fp, "%s", tempStringTwo) != EOF) {
if (strcmp(tempStringTwo, "#start") == 0) {
fscanf(fp, "%s", tempStringTwo);
while (strcmp(tempStringTwo, "#end") != 0) {
for (int j = 0; j < numUrls; j++) {
if (strcmp(tempStringTwo, urlList[j]) == 0) {
Edge e = {i, j};
insertEdge(urlGraph, e);
}
}
fscanf(fp, "%s", tempStringTwo);
}
}
}
fclose(fp);
}
return urlGraph;
}
The output of my program is incorrect, I'm trying to implement the PageRank algorithm in this code. Firstly the file information is stored into a Graph and then the pageRank is calculated. However my output does not match the correct output on the test files, so I suspect there is either something wrong with the mathematical operations in the main function or the GetGraph function. I'm not entirely sure and would like to find out.

How can I take this values to an array?

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.

C hsearch find action always return wrong data value but right key value

I am dealing with the hsearch function in my progam. I generate my key which is a char *. And the data I stored is an integer.
I always add an element without problem, but when I want to find with
ENTRY *elemp, elem;
elemp = hsearch(elem, FIND).
elemp->data is always a wrong value(not the one inserted).
Is there a known issue about that.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <search.h>
#define N 1
#define B 0
#define U 2
#define TAILLE 100000
char key[1000];
char* convTableToKeyString(int lignes, int colonnes, int joueur_tour, int tab[lignes][colonnes]) {
int indice = 0;
switch (joueur_tour) {
case 0:
key[indice++] = 'B';
break;
case 1:
key[indice++] = 'N';
break;
}
for (int i = 0; i < lignes; i++) {
for (int j = 0; j < colonnes; j++) {
switch (tab[i][j]) {
case 0:
key[indice++] = 'B';
break;
case 1:
key[indice++] = 'N';
break;
case 2:
key[indice++] = 'U';
break;
}
}
}
key[indice++] = '\0';
return key;
}
int valeur_configuration(int couleur_tour, int colonnes, int lignes, int tabEchec[lignes][colonnes]) {
ENTRY elem, *elemp;
int res;
int i,j;
int prochain_joueur = couleur_tour == B ? N : B;
int tabCase1[lignes][colonnes], tabCase2[lignes][colonnes], tabCase3[lignes][colonnes];
int lose_range = couleur_tour == B ? lignes-1 : 0;
int tabConf[3*colonnes];
int nbreCoupsPossibles = 0;
//generate the key and look if it already exist in the table
elem.key = convTableToKeyString(lignes, colonnes, couleur_tour, tabEchec);
elemp = hsearch(elem, FIND);
if (elemp != NULL) {
return (int) (elemp->data);
}
/* The value is not present in the hash, so I can calculate it */
//my code logic check the possible moves and add the value in the hash table
for (i = 0; i < lignes; i++) {
for (j = 0; j < colonnes; j++) {
int front = couleur_tour == B ? i-1 : i+1;
if (tabEchec[i][j] == couleur_tour) {
if (j != 0 && tabEchec[front][j-1] == prochain_joueur) {
/* some operations */
tabConf[nbreCoupsPossibles++] = valeur_configuration(prochain_joueur, colonnes, lignes, tabCase2);
if(tabConf[nbreCoupsPossibles-1] ==0) {
res = 1;
elem.data = (void *) res;
elemp = hsearch(elem, ENTER);
/* there should be no failures */
if (elemp == NULL) exit(EXIT_FAILURE);
return 1;
}
} // if (j != 0 && tabEchec[front][j-1] == prochain_joueur)
if (j != colonnes-1 && tabEchec[front][j+1] == prochain_joueur) {
/* some operations */
tabConf[nbreCoupsPossibles++] = valeur_configuration(prochain_joueur, colonnes, lignes, tabCase3);
if(tabConf[nbreCoupsPossibles-1] ==0) {
res = 1;
elem.data = (void *) res;
elemp = hsearch(elem, ENTER);
/* there should be no failures */
if (elemp == NULL) exit(EXIT_FAILURE);
return 1;
}
} // if (j != colonnes-1 && tabEchec[front][j+1] == prochain_joueur)
if (tabEchec[front][j] == U) {
/* some operations */
tabConf[nbreCoupsPossibles++] = valeur_configuration(prochain_joueur, colonnes, lignes, tabCase1);
if(tabConf[nbreCoupsPossibles-1] ==0) {
res = 1;
elem.data = (void *) res;
elemp = hsearch(elem, ENTER);
/* there should be no failures */
if (elemp == NULL) exit(EXIT_FAILURE);
return 1;
}
} // if (tabEchec[front][j].couleur == U)
} // if (tabEchec[i][j] == couleur_tour)
} // for (j = 0; j < colonnes; j++)
} // for (i = 0; i < lignes; i++)
if(nbreCoupsPossibles == 0) {
//Haven't move, I lost
res = 0;
elem.data = (void *) res;
elemp = hsearch(elem, ENTER);
/* there should be no failures */
if (elemp == NULL) exit(EXIT_FAILURE);
return 0;
}
i = 0;
int maxi = 0;
while (i < nbreCoupsPossibles && tabConf[i] > 0) {
maxi = maxi > tabConf[i] ? maxi : tabConf[i];
i++;
}
if (i >= nbreCoupsPossibles) {
res = -1 * (maxi+1);
elem.data = (void *) res;
elemp = hsearch(elem, ENTER);
/* there should be no failures */
if (elemp == NULL) exit(EXIT_FAILURE);
return res;
} else {
maxi = tabConf[i];
while (i < nbreCoupsPossibles) {
if (tabConf[i] < 0) {
maxi = maxi > tabConf[i] ? maxi : tabConf[i];
}
i++;
}
res = -1 * (maxi-1);
elem.data = (void *) res;
elemp = hsearch(elem, ENTER);
elemp = hsearch(elem, FIND);
/* there should be no failures */
if (elemp == NULL) exit(EXIT_FAILURE);
return res;
} // if (i >= nbreCoupsPossibles)
return 0;
}
/* Function call first call*/
int main() {
int n,m,i,j;
hcreate(TAILLE);
int colonnes;
int lignes;
char b = 'a';
scanf("%d", &n);
scanf("%d", &m);
int tabPions[n][m];
char temp[m];
//Fake : just for flushing scanf internal functions
scanf("%c", &b);
for (i = 0; i < n; i++) {
scanf("%[^\n]%*c", temp);
for (j = 0; j < m; j++) {
if (temp[j] != 'p' && temp[j] != 'P') tabPions[i][j] = U;
if (temp[j] == 'p') tabPions[i][j] = N;
if (temp[j] == 'P') tabPions[i][j] = B;
}
}
colonnes = m;
lignes = n;
int res = valeur_configuration(B, colonnes, lignes, tabPions);
printf("%d\n", res);
hdestroy();
}
I don't completely understand the program, but I think I can explain your hsearch problem.
You are reusing the global char key[1000] buffer for every key. hsearch doesn't allow that. When you add an item to the hash table, hsearch doesn't make a copy of the key string. It only copies the pointer.
Since you're using the same key buffer for all your ENTERs and your FINDs, every key in the hash table matches the one you're looking for, every time, because they're all the same string! Most of them are in the wrong hash bucket, making the result of a lookup somewhat random.
A quick fix would be to do elem.key = strdup(elem.key) just before each ENTER operation.
If you care about freeing the strings before your program exits, you'll have to work a little harder on the memory management. hsearch is not helpful in that area, since it doesn't provide an iterator.

Reading from csv file and dynamic memory allocation

My code has a memory leak problem. I don't know where I went wrong. Below is the code: I am trying to read from csv file and store a particular columns.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main ()
{
FILE *result = fopen ("C:\\Users\\pa1rs\\Desktop\\local.csv", "w");
const char *text = "LOA,NAME,";
fprintf (result, "%s", text);
char *token;
char *endToken;
int lines = 0;
char ch; /* should check the result */
FILE *file = fopen ("C:\\Users\\pa1rs\\Desktop\\samplee.csv", "r");
char line[300];
if (file == NULL) {
perror ("Error opening the file");
} else {
while (!feof (file)) {
ch = fgetc (file);
if (ch == '\n') {
lines = lines + 1;
}
}
//printf(" no of lines existing in the file %d\n\n", lines);
}
fseek (file, 0, SEEK_SET);
while ((ch = fgetc (file)) != '\n') {
// we don't need the first line on sample.csv
// as it is just the description part
}
int s[lines - 1];
int j = 0;
char *N[lines - 1];
while (fgets (line, sizeof (line), file)) {
int i = 0;
token = line;
do {
endToken = strchr (token, ',');
if (endToken)
*endToken = '\0';
if (i == 3) {
s[j] = atoi (token);
}
if (i == 12) {
N[j] = (char *) malloc (strlen (token) * sizeof (char));
strcpy (N[j], token);
}
if (endToken)
token = endToken + 1;
i++;
} while (endToken);
j = j + 1;
}
//******************************************************unigue loa
int count = 0;
int g = 0;
int h = 0;
int LOA[lines - 1];
int dd = 0;
for (dd = 0; dd < lines - 1; dd++) {
LOA[dd] = 0;
}
for (g = 0; g < lines - 1; g++) {
for (h = 0; h < count; h++) {
if (s[g] == LOA[h])
break;
}
if (h == count) {
LOA[count] = s[g];
count++;
}
}
int xw = 0;
for (xw = 0; xw < count; xw++) {
//printf("%d \t",LOA[xw]);
}
//printf("LOA Array Length is: %d \n",count);
//********************************************************
////FOR UNIQUE NAMES ARRAY
//printf("No of unique names are %d",county);
//FOR UNIQUE CAUSES ARRAY
char *sa[9] =
{ "Monticello", "Valparaiso", "Crown Point", "Plymouth", "Goshen",
"Gary", "Hammond", "Laporte", "Angola" };
int countz = 0;
int gz = 0;
int hz = 0;
char *LOAz[lines - 1];
int zero2 = 0;
for (zero2 = 0; zero2 < lines - 1; zero2++) {
LOAz[zero2] = NULL;
}
for (gz = 0; gz < lines - 1; gz++) {
for (hz = 0; hz < countz; hz++) {
if (strcmp (N[gz], LOAz[hz]) == 0)
break;
}
if (hz == countz) {
LOAz[countz] = (char *) malloc (strlen (N[gz]) * sizeof (char));
strcpy (LOAz[countz], N[gz]);
countz++;
}
}
int nz = 0;
for (nz = 0; nz < countz; nz++) {
fprintf (result, "%s,", LOAz[nz]);
}
fprintf (result, "\n");
// printf("%d",countz);
//*****************************
int i = 0;
int jjj = 0;
int xxx = 0;
int ggg = 0;
int k = 0;
int kount[count][countz];
for (xxx = 0; xxx < count; xxx++) {
for (ggg = 0; ggg < countz; ggg++) {
kount[xxx][ggg] = 0;
}
}
for (i = 0; i < count; i++) {
for (k = 0; k < countz; k++) {
for (jjj = 0; jjj < lines - 1; jjj++) {
if (LOA[i] == s[jjj]) {
if (strcmp (LOAz[k], N[jjj]) == 0) {
kount[i][k]++;
}
}
}
}
}
int ig = 0;
int ik = 0;
for (ig = 0; ig < count; ig++) {
fprintf (result, "%d,%s", LOA[ig], sa[ig]);
for (ik = 0; ik < countz; ik++) {
fprintf (result, ",%d", kount[ig][ik]);
}
fprintf (result, "\n");
}
int rrr = 0;
free (N);
for (rrr = 0; rrr < lines - 1; rrr++) {
free (LOAz[rrr]);
}
//*****************************
//fclose(result);
fclose (file);
return 0;
}
Lines I got here is 13761 and LOAz was declared with array size lines-1=13761, but unique ones I got here are only 49, So I am reallocating memory for that and remaining are unused , I think problem started there.
Please help! Thanks in Advance.
One problem in your code is that you don't allocate enough memory for strings. For example, in these lines:
N[j] = (char*) malloc(strlen(token) * sizeof(char));
strcpy(N[j], token);
// ...
LOAz[countz] = (char*) malloc(strlen(N[gz]) * sizeof(char));
strcpy(LOAz[countz], N[gz]);
The problem is that strlen returns the number of non-zero symbols in the string. However, to store the string you need one more byte, to also store the zero terminating character, so the buffer size to store s should be at least strlen(s) + 1.
Also, a better coding style is to avoid casting the return value of malloc.

testcase not running in c program

iam new to c program and facing difficulty in debugging programs.In the below code test case 2 is not running.I have found that the error is in reading interger n in the second test case.someone please hep me with this issue.Also please recommend me with some tools that can be ued for debugging c programs using terminal.Thanks for help
#include <stdio.h>
#include <stdlib.h>
int read(){
int r = 0;
char c = getchar_unlocked();
while(c >= '0' && c <= '9'){
r = r*10 + c - 48 ;
c = getchar_unlocked();
}
return r;
}
void main(){
int t = 0;
t = read();
int rr = 0;
for(rr = 0;rr < t;rr++){
int i,n = 0;
n = read();
int *p = (int *)calloc(n,sizeof(int));
for(i = 0;i < n;++i){
*(p+i) = getchar_unlocked() - 48;
}
int no,nz = 0;
for(i = 0;i < n;++i){
if(*(p+i) == 0){nz += 1;}
if(*(p+i) == 1){no += 1;}
}
int k = 0;
if(((no)%2 == 0) && ((nz)%2) == 0){
k = -1;
}
if(((no)%2 == 0) && ((nz)%2) == 1){
k = 0;
}
if(((no)%2 == 1) && ((nz)%2) == 0){
k = 1;
}
if(((no)%2 == 1) && ((nz)%2) == 1){
k = 1;
}
int result = 0;printf("%d\n",5556);
if(k == 1){
for(i = 0;i < n;++i){
if(*(p+i) == 1){
result = i+1 ;
break;
}
}
}
if(k == 0){
for(i = 0;i < n;++i){
if(*(p+i) == 0){
result = i+1 ;
break;
}
}
}
printf("%d\n",result);
}
}
Your strategy to read an integer is flawed. You don't have the logic to skip whitespaces. I would change the function name to read_int and change its implementation to
int read(){
int n;
if ( scanf("%d", &n) != 1 )
{
// Deal with the error
}
return n;
}
Also, change
*(p+i) = getchar_unlocked() - 48;
to
*(p+i) = read_int();
or a more intuitive version:
p[i] = read_int();
With those changes, I am able to read and process the numbers. But I still get the wrong output. I'll let you figure the logic error in your code.
Additional Comments
main is expected to return an int. If your compiler didn't complain about that, it's time to up the warning level. I use -Wall by default.
When you are in the process of debugging your code, it's always good to test the code that reads the input to make sure that there is no error in reading the input.
Here's what I did to your code:
#include <stdio.h>
#include <stdlib.h>
int read_int(){
int n;
if ( scanf("%d", &n) != 1 )
{
// Deal with the error.
}
return n;
}
int main(){
int t = 0;
int rr = 0;
t = read_int();
printf("t = %d\n", t);
for(rr = 0;rr < t;rr++){
int i,n = 0;
n = read_int();
printf("n = %d\n", n);
int *p = (int *)calloc(n,sizeof(int));
for(i = 0;i < n;++i){
p[i] = read_int();
printf("p[%d] = %d\n", i, p[i]);
}
int no,nz = 0;
for(i = 0;i < n;++i){
if(*(p+i) == 0){nz += 1;}
if(*(p+i) == 1){no += 1;}
}
int k = 0;
if(((no)%2 == 0) && ((nz)%2) == 0){
k = -1;
}
if(((no)%2 == 0) && ((nz)%2) == 1){
k = 0;
}
if(((no)%2 == 1) && ((nz)%2) == 0){
k = 1;
}
if(((no)%2 == 1) && ((nz)%2) == 1){
k = 1;
}
int result = 0;
// printf("%d\n",5556);
if(k == 1){
for(i = 0;i < n;++i){
if(*(p+i) == 1){
result = i+1 ;
break;
}
}
}
if(k == 0){
for(i = 0;i < n;++i){
if(*(p+i) == 0){
result = i+1 ;
break;
}
}
}
printf("%d\n",result);
}
return 0;
}

Resources