Segmentation error, what is missing in my code? - c

I'm trying to get my code to convert a text file with 3 columns, xcoor, ycoor, and a symbol with 2 characters into a 30x30 map that prints the 2nd character of the symbol with the rest of the spaces being filled with a '.' However, my code doesn't seem to run, and I get a segmentation error when I try inputting the text file, what am I doing wrong? Thanks in advance
int main(void)
{
char grid[30][30];
for(int i=0;i<30;i++){
for(int j=0;j<30;j++){
grid[i][j]='.';
}
}
int xcoor,ycoor;
char symbol[2];
while((xcoor!=0)||(scanf("%d",&xcoor)))
{
while(xcoor==0){
scanf("%d",&xcoor);
}
scanf("%d %c%c",&ycoor,&symbol[0],&symbol[1]);
grid[xcoor-1][ycoor-1]=symbol[1];
}
for(int i=0;i<30;i++){
for(int j=0;j<30;j++){
printf("%c ",grid[i][j]);
}
printf("\n");
}
return 0;
}

This may not cover ALL of your errors, but immediately I see this:
int xcoor,ycoor;
char symbol[2];
while((xcoor!=0)
Do you think xcoor has a valid value right now? Should it? Because it doesn't. You've created a variable, then before actually setting it to anything, you are checking its value.
It's more than likely your scanf call that's giving you trouble. Regardless, try actually setting these variables. It will most likely fix your issues.
See here for more info: Is reading from unallocated memory safe?

You are using an uninitialized variable xcoor in the conditional of the while statement.
You can fix that by initializing xcoor.
More importantly, you can simplify the code for reading user data and the related error checks. Here's what I suggest:
while ( scanf("%d%d %c%c", &xcoor, &ycoor, &symbol[0], &symbol[1]) == 4 )
{
if ( xcoor < 0 || xcoor >= 30 )
{
// Deal with problem.
fprintf(stderr, "Out or range value of xcoor: %d\n", xcoor);
exit(1);
}
if ( ycoor < 0 || ycoor >= 30 )
{
// Deal with problem.
fprintf(stderr, "Out or range value of ycoor: %d\n", ycoor);
exit(1);
}
grid[xcoor-1][ycoor-1] = symbol[1];
}

Related

How to solve error 6011 when cheking for-loop condition?

I am new in C and tried checking the loop condition as to find on the internet, but I get this error I am not able to solve (no other questions/answers were helpful):
void main() {
char* insert = malloc(30);
printf("Insert a Molecular Formula:\n");
gets(insert);
if (insert) {
for (int i = 0; insert[i] != '\0'; i++) {
}
} }
I get the error 6011 in VS inside the for-loop when checking insert[i] != '\0'.
I haven't found a good fix, I have tried cheking return of malloc like if(!insert){ //above code here}
but this didn't help.
Thanks in advance.
Error C6011 is a warning, not an error, so your code will run, but it's not bad to handle these issues if Visual Studio is indicating them.
To get the warning to go away, fix your loop like so:
if (insert)
{
for (int i = 0; insert[i] != '\0'; i++) {
}
}

C linear search failing to compare two strings using strcmp, compiles fine

The program runs and exits with code 0, but gives no output, it's supposed to be a linear search program
I looked to other similar problems, i tried to end the array with \n. tried instead of just relying in just the "if (strcmp=0)" to make something with the values strcmp return, I'm very new and for what I'm learning not very good, just made things worst, i tried to look if it was about the char* values strcmp expect, but couldn't find the problem
#include <stdio.h>
#include <string.h>
#define max 15
int lineal(char elementos[], char elebus)
{
int i = 0;
for(i=0; i<max; i++)
{
if(strcmp(elementos[i], elebus)==0)
{
printf("Elemento encontrado en %d,", i); //element found in
}
else
{
printf("elemento no encontrado"); //not found
}
}
}
int main()
{
char elebus[50];
char elementos[max][50]= {"Panque", "Pastel", "Gelatina", "Leche", "Totis", "Tamarindo" "Papas", "Duraznos", "Cacahuates", "Flan", "Pan", "Yogurt", "Café", "Donas", "Waffles"};
printf("Escribir elemento a buscar\n");
scanf("%s", elebus);
int lineal(char elementos[], char elebus);
}
The expected output would be element found in "i" position, if found
if not found print "not found"
You want to pass it a string to find, not just one character Also, elementos should be a 2D array. Change the signature of your function to this:
int lineal(char elementos[max][50], char *elebus)
Also, in main, you don't call the function. Instead, you just declare it again. call it like this:
lineal(elementos, elebus);
Furthermore, I would change it to return void instead of int. You're neither returning anything (that's undefined behavior) nor are you using the return value anywhere. But I assume that this isn't the final version and you want to return the index at some point.
On a side note, right now it's printing that it didn't find the element for every time it didn't match, even if it does find it eventually. I would recommend this instead:
for (i = 0; i < max; i++)
{
if (strcmp(elementos[i], elebus) == 0)
{
printf("Elemento encontrado en %d\n,", i); //element found in
return;
}
}
printf("elemento no encontrado\n"); //not found
This is printing "elemento no encontrado" only once, and only when the string wasn't found.

C - Linked List Segmentation Fault During Display

Edit 2: I realized that I did not have a "Not found" result for any query not in the database. Changes have been made to introduce this feature. Here is the current test and test output:
Input:
3
sam
99912222
tom
11122222
harry
12299933
sam
edward
harry
Output:
Not found
=0
Not found
=0
Not found
=0
Not found
=0
sam
=99912222
Not found
=0
Not found
=0
Not found
[Infinite loop continues]
Edit: I have changed a few things in the while loop in display(). I am now getting an infinite loop printing "=0" except for the third or fourth cycle through the search. Hmmm...
By the way, thanks for the reminder of testing strings with ==. Seems like a no-brainer now.
I have done some searching and have yet to be able to understand where I have gone wrong with my code. I am working on a challenge which will result in a simple phone-book program. It will take input of a number (the number of entries to be added) then the names and associated phone numbers (no dashes or periods). After the entries have been added then the user can search for entries by name and have the number displayed in the format "name=number".
The code throws a segmentation fault with the while loop in the display() function. I assume that I am attempting to print something assigned as NULL, but I cannot figure out where I have gone wrong. Any help would be very appreciated.
Lastly, the challenge calls for me to read queries until EOF; however, this confuses me since I am to accept user input from stdin. What does EOF look like with stdin, just a register return (\n)?
(PS: This is my first attempt at linked lists, so any pointers would be greatly appreciated.)
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
void add_entry(void);
void display(void);
struct phonebook {
char name[50];
int number;
struct phonebook *next;
};
struct phonebook *firstp, *currentp, *newp;
char tempname[50];
int main() {
int N;
firstp = NULL;
scanf("%d", &N);
for (int i = 0; i < N; i++) {
add_entry();
}
display();
return 0;
}
void add_entry(void) {
newp = (struct phonebook*)malloc(sizeof(struct phonebook));
if (firstp == NULL) firstp = currentp = newp;
else {
currentp = firstp;
while (currentp->next != NULL)
currentp = currentp->next;
currentp->next = newp;
currentp = newp;
}
fgets(currentp->name, 50, stdin);
scanf("%d", &currentp->number);
currentp->next = NULL;
}
void display(void) {
while (strcmp(tempname, "\n") != 0) {
currentp = firstp;
fgets(tempname, 50, stdin);
while (strcmp(currentp->name, tempname) != 0) {
if (currentp->next == NULL) {
printf("Not found\n");
break;
}
currentp = currentp->next;
}
printf("%s=%d\n", currentp->name, currentp->number);
}
}
Your problem is that you never find the entry you're looking for. The expression currentp->name != tempname will always be true, since those are always unequal. In C, this equality test will not compile into a character-by-character comparison, but into a comparison of pointers to currentp->name and tempname. Since those are never at the same addresses, they will never be equal.
Try !strcmp(currentp->name, tempname) instead.
The reason you crash, then, is because you reach the end of the list, so that currentp will be NULL after your loop, and then you try to print NULL->name and NULL->number, actually causing the crash.
Also, on another note, you may want to start using local variables instead of using global variables for everything.
Not sure if this solves the problem, but you can't directly compare strings with != in C. You need to use if( strcmp( string1, string2 ) == 0 ) to check.
fgets doesn't take EOF (= -1) like getchar does, but it does include '\n' and pad the rest with NULL (= 0) so checking for EOF is not really helpful, but yes you can stop after \n or NULL.

Stack implemented as an array defaulting first value to 0 in C

I have an assignment where I am supposed to use this very very simple (or so I thought) stack that my teacher wrote in C, just using an array. From this, I have to implement reverse polish notation from a text file.
In order for me to implement this, I am using a stack, pushing values on until I hit an operation. I then do the operation and push the result back onto the stack until the user hits p to print the value.
The problem is, for some reason, my professor's implementation of the stack array defaults the first (index 0) value to 0. Printing the stack without pushing anything onto it should result in null but it appears the output is 0.
Here is my professor's implementation of the stack:
#define STK_MAX 1024
#define ELE int
ELE _stk[STK_MAX];
int _top = 0;
void stk_error(char *msg)
{
fprintf(stderr, "Error: %s\n", msg);
exit(-1);
}
int stk_is_full()
{
return _top >= STK_MAX;
}
int stk_is_empty()
{
return _top == 0;
}
void stk_push(ELE v)
{
if ( stk_is_full() )
stk_error("Push on full stack");
_stk[_top++] = v;
}
ELE stk_pop()
{
if ( stk_is_empty() )
stk_error("pop on empty stack");
return _stk[--_top];
}
void print()
{
for(int i = 0; i <= _top; ++i)
printf("%d ", _stk[i]);
printf("\n");
}
I realize that the print statement will print a value that has not been pushed yet, but the problem is, is that when I don't print it, it still ends up there and it ends up screwing up my rpn calculator. Here is what happens when I do this:
// input
stk_push(2);
print();
stk_push(4);
print();
// output
2 0
2 4 0
How do I get rid of the 0 value that is affecting my calculator? Doing stk_pop() after the pushing the first value onto the stack didn't seem to work, and checking that top == 0, then directly inserting that element before incrementing _top didn't work.
When you are printing, loop from 0 to (_top - 1), since your top most element is actually at _top - 1. Hint : Look at your pop/push method.
void print()
{
for(int i = 0; i < _top; ++i)
printf("%d ", _stk[i]);
printf("\n");
}
"The problem is, is that the rpn calculator relies on the TOS being accurate. When I do pop() though, it will pop 0 and not the real TOS."
Sounds like a problem with your calculator implementation. You assumed the top of the stack would be null, but that's not the case for your professors stack implementation. Simply a invalid assumption.
Instead he's provided a stk_is_empty() method to help determine when you've pop everything.
If you need to pop all elements, you'll need to break on the condition of stk_is_empty().
stk_push(2);
stk_push(4);
while( stk_is_empty() == false)
{
stk_pop();
}
Of course in reality you'd be setting the pop return to a variable and doing something with it. The key point is leveraging stk_is_empty().
I haven't written C++ in few years so hopefully I didn't make a minor syntax error.

fscanf not saving the data to struct?

I have an array of structs and they get saved into a file. Currently there are two lines in the file:
a a 1
b b 2
I am trying to read in the file and have the data saved to the struct:
typedef struct book{
char number[11];//10 numbers
char first[21]; //20 char first/last name
char last[21];
} info;
info info1[500]
into num = 0;
pRead = fopen("phone_book.dat", "r");
if ( pRead == NULL ){
printf("\nFile cannot be opened\n");
}
else{
while ( !feof(pRead) ) {
fscanf(pRead, "%s%s%s", info1[num].first, info1[num].last, info1[num].number);
printf{"%s%s%s",info1[num].first, info1[num].last, info1[num].number); //this prints statement works fine
num++;
}
}
//if I add a print statement after all that I get windows directory and junk code.
This makes me think that the items are not being saved into the struct. Any help would be great. Thanks!
EDIT: Okay so it does save it fine but when I pass it to my function it gives me garbage code.
When I call it:
sho(num, book);
My show function:
void sho (int nume, info* info2){
printf("\n\n\nfirst after passed= %s\n\n\n", info2[0].first); //i put 0 to see the first entry
}
I think you meant int num = 0;, instead of into.
printf{... is a syntax error, printf(... instead.
Check the result of fscanf, if it isn't 3 it hasn't read all 3 strings.
Don't use (f)scanf to read strings, at least not without specifying the maximum length:
fscanf(pRead, "%10s%20s%20s", ...);
But, better yet, use fgets instead:
fgets(info1[num].first, sizeof info1[num].first, pRead);
fgets(info1[num].last, sizeof info1[num].last, pRead);
fgets(info1[num].number, sizeof info1[num].number, pRead);
(and check the result of fgets, of course)
Make sure num doesn't go higher than 499, or you'll overflow info:
while(num < 500 && !feof(pRead)){.
1.-For better error handling, recommend using fgets(), using widths in your sscanf(), validating sscanf() results.
2.-OP usage of feof(pRead) is easy to misuse - suggest fgets().
char buffer[sizeof(info)*2];
while ((n < 500) && (fgets(buffer, sizeof buffer, pRead) != NULL)) {
char sentinel; // look for extra trailing non-whitespace.
if (sscanf(buffer, "%20s%20s%10s %c", info1[num].first,
info1[num].last, info1[num].number, &sentinel) != 3) {
// Handle_Error
printf("Error <%s>\n",buffer);
continue;
}
printf("%s %s %s\n", info1[num].first, info1[num].last, info1[num].number);
num++;
}
BTW: using %s does not work well should a space exists within a first name or within a last name.

Resources