Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

program run crazy

Status
Not open for further replies.

elaiza

Programmer
May 14, 2010
1
US
hello,
am running a c program in visual C++ 2010 express,when i type the below code it keep running and after it give me the message that myfilename.exe has encountered a problem and needs to close.when i choose ok it give me the output.when i change the while loop to for loop and decrease the loop counter to 4 (for (int n=0;n<4;n++)) it work fine.any idea plz

Code:
void distance()
{
FILE* output1;
FILE* output2;
char str[11];
int i=0;
int mslat,mslong,bslat,bslong;

output1 = fopen("fdf.txt", "r");
output2 = fopen("rd.txt", "w");
while (!feof(output1)) {
fscanf(output1, "%s ", &str);
if(strstr(str,"RxLev:") != NULL )
{

fprintf(output2,"\n");

i=1;
}//--------if
else if(i==1)
{

fprintf(output2,"%s\t", str);
i=2;

}
else if(i==2)
{
fscanf(output1, "%s ", &str); 
fprintf(output2,"%s\t", str);
i=3;
}
else if(i==3)
{
fscanf(output1, "%s ", &str); 
fprintf(output2,"%s\t", str);
//fprintf(output2,"%lf\t", mslong);
i=4;
}
else if(i==4)
{
fscanf(output1, "%s ", &str); 
fscanf(output1, "%s ", &str);
fscanf(output1, "%s ", &str);
fprintf(output2,"%s\t", str);
i=5;
}
else if(i==5)
{
fscanf(output1, "%s ", &str); 
fprintf(output2,"%s\t", str);
i=6;
}



}
fclose(output1);
fclose(output2);
return;
}
 
You are reading into str, which is an array of size 11. Str is a local variable (stack space) and a read that is too large will trash the stack and possibly the return pointer. Are you certain that the string reads are ALWAYS less than 11 with a NULL character?

I'm not sure about why the for loop works, but it would limit the stack usage and data range of your file.
 
There are some errors (and other defects;) in your code.

1. Why your input file was named as 'output1'? Is it a good idea to designate white color constant as BLACK?
;)

2. Never use this read stream pattern:
Code:
FILE* f = fopen(...);
while (!feof(f)) {
   ...
}
- Always test f after fopen:
Code:
if (!fopen) {
  /* stop processing, file was not opened! */
}
- This loop can't read empty files correctly. The feof indicator is cleared after fopen, so this code 'reads' and 'processes" nothing in the first loop of while statememt.
- This loop 'reads' inexistent portion after the last non-blank item in the file (see the previous point).

3. Always test fscanf return code, in your case:
Code:
if (fscanf(f,"%s",...) != 1) {
  /* Break loop: fscanf failed! */
}

4. Reread Noway2's post and never use %s specificator in fscanf...
 
Sorry, correct fopen failed condition:
Code:
if (!f)
/* or */
if (f == 0)
 



You are passing the address of the pointer in fscanf.... Pass the pointer instead.

Amiel Summers

amielzz@netscape.net
 
str == &str if str is an array ;)
It's OP case exactly...
 
...hmmmmm.

str is a variable, a pointer to an array of type char (actually str is a pointer to the first element of the array of characters).

So, the statement &str provides the address of the variable str (a pointer in this case).

Therefore, &str is the address of a pointer, or the address of the address... not the address of the array... which is contained in str.

The string search function can be expected to search through program memory starting at the value passed as the address of an array of char, and continue until it encounters a null, or some other system imposed limit.

The code may compile but it will not function as expected.
It will likely function [pc3] as elaiza's title describes.

Amiel Summers

amielzz@netscape.net
 
Dear Amiel,
reread The C Programming Language definition...
...or try to print out str and &str values (str must be an array, of course;)...
 
@Amiel

> str is a variable, a pointer to an array of type char
You're already wrong.

An array is NOT always a pointer.
In particular, 6.12 which discusses this very issue.

> (actually str is a pointer to the first element of the array of characters).
Yes, when you pass it to a function say.

But before then, it's still an array.
Here's an example showing when it's still an array, and when it's become a pointer.
Code:
#include <stdio.h>
#include <stdlib.h>

void foo ( char array[10] ) {
    char **p = &array;  // NOW taking it's address yeilds char**
    // This isn't the array itself, it is a pointer containing the address of the array
    printf("Size of 'array' (not really) passed to function=%lu\n", (unsigned long)sizeof(array) );
    printf("array is at %p, p points to %p\n", (void*)array, (void*)*p );
}
void bar ( char *array ) {
    char **p = &array;  // NOW taking it's address yeilds char**
    printf("Size of 'array' (not really) passed to function=%lu\n", (unsigned long)sizeof(array) );
    printf("array is at %p, p points to %p\n", (void*)array, (void*)*p );
}

int main(void) {
    char str[50];
    {
        printf("Size of array in scope=%lu\n", (unsigned long)sizeof(str) );
        foo( str );
        bar( str );
    }
    {
        char *p = str;
        char *q = &str[0];      // same as p
        //char **s = &str;        // this is WRONG, str is NOT a char*, so taking it's address is NOT char**
        char (*t)[50] = &str;   // address of array is a pointer to the WHOLE array.
        printf("Pointer values=%p %p %p\n", (void*)p, (void*)q, (void*)t );
    }
    return 0;
}

$ gcc foo.c
$ ./a.out 
Size of array in scope=50
Size of 'array' (not really) passed to function=4
array is at 0xbfc7a62e, p points to 0xbfc7a62e
Size of 'array' (not really) passed to function=4
array is at 0xbfc7a62e, p points to 0xbfc7a62e
Pointer values=0xbfc7a62e 0xbfc7a62e 0xbfc7a62e
If the array name was always a pointer, then sizeof would never work, and taking the address of an array would always result in the same type of pointer.



--
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
 

Yes, when you pass it to a function.

We are using the fscanf function.

fscanf expects an address.

str is an address.

&str is the address of the address.

Amiel Summers

amielzz@netscape.net
 
Incidently. Just for the heck of it I visited the link that Salem included in his post...

Clearly, that somewhat spiritual presentation, is intented to elicit a sense of mystery about things that are not the least bit mysterious.

Example for item 6.6b; we are talking about initializing storage. vs. an assignment statement. The initialization instructions are written into the binary at compile time using immediate data.

I'm going to answer one more, although every single one of them can be answered...

6.24. Yes. But you can only do things like what 6.5 mentions when using Visual Basic (or simular). And 6.6 is an example of how it works; you just need to know that to call it.

Thanks for showing me that... Reminds me of myself working on Routers and Switches.... If only I knew what the names of things were [ponder], I'd be O.K.



Amiel Summers

 
> &str is the address of the address.
NO NO NO - you didn't read anything did you?

Code:
char array[10];
scanf( "%s", array );  // pointer to first element
// This is unusual
scanf( "%s", &array ); // pointer to THE WHOLE ARRAY
There is NOT an invisible char* variable when you point at the whole array, so you can't just say "the address of the address".

Compare with
Code:
char array[10];
char *pa = array;
scanf( "%s", pa );  // pointer to first element (via the assignment)
// This is BROKEN
scanf( "%s", &pa ); // pointer to pointer (nothing to do with array at all)


Since you seem to be struggling with the idea of having different types of pointer pointing to the same address, consider this:
Code:
struct foo { int bar; int baz; };

struct foo mydata;
struct foo *pa = &mydata;
int *pb = &mydata.bar;
Print out pa and pb - different types, same value.

Same for array vs. &array (when the array is in scope).
Different types, same value.



--
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
 
>str is an address.

The point is that an array name is NOT converted into the pointer to the first element in &array_name expression (the C Standard 6.3.2).

So str is NOT an address in &str.
 
The explanations requred here, have to do with basic data types.

The variables declared in a C program are never 'converted' once initialized.

Such that; once str is declared it will always be of that 'type' (In addition to the 'reference' link provided in your posts, I noticed your use of a cast to type *void when displaying your results).

We can create a new variable and assigned a 'cast' value to it. We can call it 'coverted' if that pleases you but in reality the variable str will remain as initially initialzed.

The character array in this particular language is handled in a special way. Functions that take character arrays as arguments know how to handle the character array (many feel more comfortable referring to it as 'buffer').

Simply stated; the function starts reading at the adddress provided and reads sequentially, until the null charcter is encountered. If the null charcter is not found at the desired location the function can be expected to continue to read with often undesirable results.

This has never changed in the language since day one.

If one adds the 'address of' operator, when suppying the arg str in this instance. What can be expected to be the result when fscanf reads in values?

... beats me [yinyang].

Amiel Summers

 
An array of type (any type except void, of course) name in C IMPLICITLY converted to a pointer to the first array element in all contexts EXCEPT expressions &name (unary operator & argument) and sizeof name (operator sizeof argument). So (str) expression implicitly yields an address and (&str) expression explicitly yeilds an address - that's all.

That's why for every (not only char) array str expressions (str) and (&str) yield the same result.

The fscanf function waits a pointer to char for %s format specificator. It reads chars from the stream into this char array until whitespace char occured then adds zero byte to this array. It does not know what's this array size (alas, it has a pointer to the start of memory chunk only).

That's why %s format specificator of scanf family functions is harmful.
 
Friend.

Judging by the language that you use, you have referred to the reference. That's wonderful.

However I never asked you a question about anything.

Please don't waste your time 'explaining' anything to me.

I never asked a question, someone else posed a question here.

You have provided some memorable, noteworthy and illustrative responses. Let's leave it at that.

Thanks.

Amiel Summers

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top