-1

I never saw that before:

enter image description here

What is the bottom left corner above? The latest version of the program is

#include <stdio.h>
#include <stdlib.h> 
int main(int argc, char **argv)
{
   int ch;
   char file_name[25] = "/proc/scsi/scsi";
   FILE *fp; 
   fp = fopen(file_name,"r"); // read mode 
   if (fp == NULL)
   {
      perror(file_name);
      exit(EXIT_FAILURE);
   } 
   printf("The contents of %s file are :\n", file_name); 
   while ((ch = fgetc(fp)) != EOF)
      putchar(ch); 
   fclose(fp);
   return 0;
}

Test

$ cc driveinfo.c;./a.out 
The contents of /proc/scsi/scsi file are :
Attached devices:
Host: scsi0 Channel: 00 Id: 00 Lun: 00
  Vendor: ATA      Model: WDC WD2500JS-75N Rev: 10.0
  Type:   Direct-Access                    ANSI  SCSI revision: 05
Host: scsi1 Channel: 00 Id: 00 Lun: 00
  Vendor: ATA      Model: ST3250824AS      Rev: 3.AD
  Type:   Direct-Access                    ANSI  SCSI revision: 05
Host: scsi2 Channel: 00 Id: 00 Lun: 00
  Vendor: TSSTcorp Model: DVD+-RW TS-H653A Rev: D300
  Type:   CD-ROM                           ANSI  SCSI revision: 05
Host: scsi3 Channel: 00 Id: 00 Lun: 00
  Vendor: Optiarc  Model: DVD-ROM DDU1681S Rev: 102A
  Type:   CD-ROM                           ANSI  SCSI revision: 05
Host: scsi4 Channel: 00 Id: 00 Lun: 00
  Vendor: Lexar    Model: USB Flash Drive  Rev: 1100
  Type:   Direct-Access                    ANSI  SCSI revision: 00
Host: scsi5 Channel: 00 Id: 00 Lun: 00
  Vendor: WD       Model: 5000AAKB Externa Rev: l108
  Type:   Direct-Access                    ANSI  SCSI revision: 00

The following reproduces the strange output:

#include <stdio.h>
#include <stdlib.h> 
int main(int argc, char **argv)
{
   int ch;
   char file_name[25] = "/proc/scsi/scsi-notExist";
   FILE *fp; 
   fp = fopen(file_name,"r"); // read mode 
   if (fp == NULL)
   {
      perror(&file_name[25]);
      exit(EXIT_FAILURE);
   } 
   printf("The contents of %s file are :\n", file_name); 
   while ((ch = fgetc(fp)) != EOF)
      putchar(ch); 
   fclose(fp);
   return 0;
}

Update

The clang compiler will warn but not (g)cc:

$ clang -Wconversion cpu-disk-info.c
cpu-disk-info.c:14:15: warning: array index of '25' indexes past the end of an
      array (that contains 16 elements) [-Warray-bounds]
      perror(&file_name[25]);
              ^         ~~
cpu-disk-info.c:6:4: note: array 'file_name' declared here
   char file_name[] = "/proc/scsi/scsi";
   ^
1 warning generated.
dev@dev-OptiPlex-745:~$ gcc -Wconversion cpu-disk-info.c
dev@dev-OptiPlex-745:~$ 
Niklas Rosencrantz
  • 25,640
  • 75
  • 229
  • 424
  • 3
    I've seen this once. I think it tried to print a byte that doesn't have a "visual representation". – Rodrigo Siqueira Mar 06 '13 at 20:01
  • I experimented with both `file_name` and `&file_name[25]` and even `file_name[25]`. I updated the question. Thank you for the comments. – Niklas Rosencrantz Mar 06 '13 at 20:13
  • 2
    Looks like `file_name` contained some garbage. So a) the file was not found, and b) the contents of `file_name` could not be properly printed. Can you recreate the bad output? – Daniel Fischer Mar 06 '13 at 20:21
  • 1
    Well, when you passed `file_name` it worked fine, right? I think that in the image that thing would make more sense if you've passed `file_name[25]`, because it is the `NULL` byte. – Rodrigo Siqueira Mar 06 '13 at 20:21
  • 1
    Passing a `file_name` that was a `\0` would work ok, as it's a valid string. Though `file_name[25]` would be out of bounds, and might crash or cause garbage. – teppic Mar 06 '13 at 20:25
  • Passing `file_name[25]` to perror does not compile. I try to reproduce what I saw during my experiments. What I saw came from a program that compiled. – Niklas Rosencrantz Mar 06 '13 at 20:30
  • 1
    Yeah! Very well seen! `file_name[25]` is out of bounds. – Rodrigo Siqueira Mar 06 '13 at 20:31
  • And it seems that passing `&file_name[25]`to perror will display garbage. – Niklas Rosencrantz Mar 06 '13 at 20:33
  • 1
    You can pass `file_name[25]` to the function but it's wrong. It's passing an out of bounds `char` as a memory address. `&file_name[25]` is an out of bounds pointer. Anything from `&file_name[0]` to `[24]` is ok to pass, but will be wrong unless it's `0`. – teppic Mar 06 '13 at 20:34
  • 1
    You're passing a pointer one past the end of the array. There's probably some uninitialised garbage there. – Daniel Fischer Mar 06 '13 at 20:40
  • The clang compiler will warn but not (g)cc. Thank you all. – Niklas Rosencrantz Mar 06 '13 at 21:05

3 Answers3

2

It's most likely due to not passing a valid const char* to void perror(const char *s), which makes the file name in <filename>: No such file or directory output as garbage/non printable characters.

The perror() function shall map the error number accessed through the symbol errno to a language-dependent error message, which shall be written to the standard error stream as follows:

First (if s is not a null pointer and the character pointed to by s is not the null byte), the string pointed to by s followed by a colon and a .

Then an error message string followed by a .

Community
  • 1
  • 1
Joachim Isaksson
  • 176,943
  • 25
  • 281
  • 294
  • I can reproduce the error with `&file_name[25]`to perror which compiles without warning and will display garbage. I hope this is in line with what you say. I updated the question with my findings. Thanks! – Niklas Rosencrantz Mar 06 '13 at 20:35
  • 1
    @NickRosencrantz Yes, `perror(&file_name[25]);` is a pointer to the 26'th character of your string, which is out of bounds and is not a valid char pointer to pass in. – Joachim Isaksson Mar 06 '13 at 20:36
  • The clang compiler will warn but not (g)cc. I updated again with my findings. Thank you for the information. I'm learning C and compilers. – Niklas Rosencrantz Mar 06 '13 at 21:05
1

I think you correct the warning driveinfo.c:17 or post your code. And its OK ;)

Good luck !

Quentin Perez
  • 2,833
  • 20
  • 22
1

"varning att skicka heltal utan konvertering ..." sounds like it's a call to perror with something that isn't a string, perhaps?

If you post the code, we can probably see more clearly, but I'm pretty sure that warning and the output is related.

Edit: If you pass filename[25] to the function, I expect this warning. If you pass &filename[25], then you are probably passing in something that isn't a string at all, so some random bytes gets printed, which could print almost anything.

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
  • Yes, I experimented with both `file_name` and `&file_name[25]` and even `file_name[25]`. I updated the question. Thank you for the answers, more background is from http://codereview.stackexchange.com/questions/23534/possible-improvements-for-this-small-c-program – Niklas Rosencrantz Mar 06 '13 at 20:15