0

fgets() returns a string from a provided stream. One is stdin, which is the user input from the terminal. I know how to do this, but if I am using compiled c code in applications, this is not very useful. It would be more useful if I could get a string from a file. That would be cool. Apparently, there is some way to provide a text file as the stream. Suppose I have the following code:

#include <stdio.h>

int main(int argc, const char *argv){
    char *TextFromFile[16];
    fgets(TextFromFile, 16, /*stream that refers to txt file*/);
    printf("%s\n", TextFromFile);
    return 0;
}

Suppose there is a text file in the same directory as the c file. How can I make the printf() function print the contents of the text file?

  • 6
    Warning: `char* x[16]` is an array of *sixteen character pointers*, not an array of sixteen characters. If this code compiles quietly you need to turn on more warnings because that `fgets` call is invalid. – tadman Dec 05 '18 at 20:24
  • 3
    [man fopen](https://linux.die.net/man/3/fopen) – dbush Dec 05 '18 at 20:27
  • Your question states the text file is in the same directory as the C source file. There is in general no way for the running program to know the directory of the C source file from which it was compiled. You will have to make some sort of arrangement to convey this information or to put the text file in a known location. (Keeping it in the same directory as the executable file is a possibility, as that directory can be derived from the `argv[0]` passed to `main`.) – Eric Postpischil Dec 05 '18 at 20:36
  • Possible duplicate of ["#include" a text file in a C program as a char\[\]](https://stackoverflow.com/questions/410980/include-a-text-file-in-a-c-program-as-a-char) – NoDataFound Dec 05 '18 at 21:24
  • 1
    @NoDataFound How is it even remotely a duplicate? –  Dec 05 '18 at 21:54
  • 1
    Because you say _suppose there is a text file in the same directory as the c file. How can I make the printf function print the contents of the text file?_ You don't ask _how to read the content of any file on the filesystem_ (which is answered by ryyker). And if you want to read the whole file that's another matter involving buffer and reallocation which is answered by this one: https://stackoverflow.com/questions/3381080/reading-all-content-from-a-text-file-c – NoDataFound Dec 05 '18 at 22:36

2 Answers2

2

Given the following is defined;

char *TextFromFile[16];

char TextFromFile[16]; //note "*" has been removed 
const char fileSpecToSource[] = {"some path location\\someFileName.txt"};//Windows
const char fileSpecToSource[] = {"some path location/someFileName.txt"};//Linux

From within a function, the statement:

FILE *fp = fopen(fileSpecToSource, "r");//file location is local to source directory.

if successful (i.e. fp != NULL), fp can be used as the stream argument in:

fgets(TextFromFile, 16, fp);
ryyker
  • 22,849
  • 3
  • 43
  • 87
  • 1
    The question states the file to be read is in the same directory as the C source file. The code in this answer opens a file in the current working directory. There is no reason to expect those to be the same. – Eric Postpischil Dec 05 '18 at 20:35
  • i get the error: error: initializer element is not constant FILE *fp = fopen(".//txt.txt", "r"); the fopen part is highlighted –  Dec 05 '18 at 20:36
  • @Eric - will modify my comments etc. Thank you. – ryyker Dec 05 '18 at 20:37
  • @Asadefa: That error message reveals you put the `FILE *fp = …;` statement at file scope (that is, outside of any function). Non-constant initializers are not allowed there. Put it inside a function instead. – Eric Postpischil Dec 05 '18 at 20:38
  • I do that and when I try to print it, I get no warnings but I get a segmentation fault. –  Dec 05 '18 at 20:43
  • @Asadefa - Change `char *TextFromFile[16];` to `char TextFromFile[16];` – ryyker Dec 05 '18 at 20:50
  • I gave it plenty of space –  Dec 05 '18 at 20:50
  • @Asadefa - Actually, you gave it no space. See my edit above, `char TextFromFile[16]; //note "*" has been removed`. As is in the original, `fgets()` is given a pointer with no memory to write to. Segmentation fault is usually the result, if you are lucky. – ryyker Dec 05 '18 at 20:53
  • still gives me segmentation fault. Probably because it is not recognizing. How do I make a path to a file on a unix based operating system? –  Dec 05 '18 at 21:02
  • @Asadefa - `const char path[] = {"./file.txt"};` With the correct file name, and if the file is located in the same directory from which you are executing the executable, then this will work. – ryyker Dec 05 '18 at 21:06
  • 2
    @Asadefa: Sorry, but you should stop posting follow-up questions in comments. Stack Overflow is not a code-writing service, and comments such as “I gave it plenty of space” do not show the actual code you tried. You can post a new question with a [Minimal Complete and Verifiable Example](https://stackoverflow.com/help/mcve), but do not expect to write your program by asking about every little thing.There are other resources for learning to program that are more suitable. – Eric Postpischil Dec 05 '18 at 21:12
0

Later I found out the problem. fopen is stupid. Using ./file.txt or others will not work. I need to use the whole file path to do it.

FILE (*File) = fopen("/home/asadefa/Desktop/txt.txt", "r");
char FData[0x100];
memset(FData, '\0', 0x100);
for(z = 0; z < 0x100; ++z) {
    fgets(FData, 0x100, File);
}
fclose(File);

I should have noted that the full file path is used.

  • Why `memset`? Why a loop that will overwrite lines as soon as they are read? Why no `fclose`? –  Dec 08 '18 at 02:41
  • Its purpose is to make sure all the allocated memory is empty before using it. –  Dec 08 '18 at 02:43
  • I know it is not critical, but I do it just in case –  Dec 08 '18 at 02:45
  • @Asadefa Just in case what? And no, it's not really stupid; current directory notation works fine as long as it's actually correct. – Dave Newton Dec 08 '18 at 07:09
  • You should check the return value of `fopen` and do something if it's NULL, indicating that opening the file failed (instead of getting a segfault and wondering why) – M.M Dec 08 '18 at 21:41
  • @M.M "doing something if it's NULL" Doing what? –  Dec 08 '18 at 21:42
  • Print an error message and exit the program would be one option – M.M Dec 08 '18 at 21:46
  • @M.M like using exit(1) –  Dec 08 '18 at 21:49