I'm trying to get my open function to work with this program, it is reading the input correctly, as I can see if I printf the file name after I type it in, but my open function must be wrong, I can't seem to figure out what is wrong with it and it keeps returning -1 and exiting. I am trying to just open a file called tester.txt and I'm using a virtual machine running ubuntu. Any help is appreciated,thanks everyone.
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
int main(){
int bytes_read = 1;
int nbytes = 32;
char buffer[32];
char s[] = "name";
printf("Welcome to File Copy by %s!\n", s);
char *inputFile = NULL;
puts("Enter the name of the source file: ");
bytes_read = getline(&inputFile, &nbytes, stdin);
//if fail exit
int inputOpen = open("inputFile", O_RDONLY);
//if fail exit
if (inputOpen == -1){
printf("file not found.\n");
return -1;
}
return 0;
}
No matter what is entered as the name of the file, you try to open a file called "inputFile". You need to add code to extract the filename from the line entered.
This would be one way:
char *eol;
bytes_read = getline(&inputFile, &nbytes, stdin);
eol = strchr(inputFile, '\n');
if (eol != NULL) // remove end of line
*eol = 0;
int inputOpen = open(inputFile, O_RDONLY);
Related
I have trouble understanding the _popen() function in c. When doing this
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *cmd;
cmd = _popen("whoami", "r");
if(cmd == NULL) {
printf("ERROR!");
return 1;
}
char buffer[256];
fgets(buffer, sizeof(buffer), cmd);
printf("Output: %s", buffer);
_pclose(cmd);
return 0;
}
I get the desired output. When doing it that way however,
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *cmd;
cmd = _popen("cmd /K", "rw");
if(cmd == NULL) {
printf("ERROR!");
return 1;
}
fprintf(cmd, "whoami\n");
char buffer[256];
fgets(buffer, sizeof(buffer), cmd);
printf("Output: %s", buffer);
_pclose(cmd);
return 0;
}
I just get an error. I read somewhere that _popen() doesn't support both reading and writing at the same time, but i have no clue on how to make it so i can open "a new console" and read from it and write to it at the same time. What would be an effective way to do so?
Is there a way to redirect output of a command line which returns integer as an output to a variable in C?
for example, if the command is "cmd", then is there a way to redirect its output (an integer) and store it in variable in C?
I tried using popen and fgets but it seems to be working only with characters. Any suggestions?
It works perfectly fine with popen and fgets:
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char *argv[])
{
const char *cmd = argc > 1 ? argv[1] : "echo 42";
char buf[32];
FILE *fp = popen(cmd, "r");
if( fp == NULL ){
perror("popen");
return 1;
}
if( fgets(buf, sizeof buf, fp) == buf ){
int v = strtol(buf, NULL, 10);
printf("read: %d\n", v);
}
return 0;
}
If you want to convert a character string from the standard input, you could use fgets and then use atoi to convert the input to an integer.
If you want to convert the output of a command, let's say ls and store the output of the command to a variable, you could learn about fork, dup2, pipe, and exec function family.
More about this topic on this tutorial : Capture the output of a child in C. This tutorial also provide an example with popen if you want to keep things "high level".
Here is an even simpler example using popen() and fscanf():
#include <errno.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
FILE *fp = popen("date '+%s'", "r");
long seconds;
if (fp == NULL) {
fprintf(stderr, "popen failed: %s\n", strerror(errno));
return 1;
}
if (fscanf(fp, "%ld", &seconds) == 1) {
printf("epoch seconds: %ld\n", seconds);
pclose(fp);
return 0;
} else {
fprintf(stderr, "invalid program output\n");
pclose(fp);
return 1;
}
}
I'm writing a client-server model in C which works using fifos. I send a file name plus a name for a unique fifo for the client to recieve the data from the client and the server opens the file and writes the first line of it on the fifo. The thing is that even if the file exists i get a segmentation fault when opening it. Seems like the fopen() function works but I still get the error. If the file doesn't exist it just sends an empty string.
Here is client.c :
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#define BUFSIZE 512
struct sent {
char name[BUFSIZE];
char fifo[BUFSIZE];
};
int main()
{
char name[BUFSIZE];
char recieved[BUFSIZE];
int client_server_fifo;
char cs_fifo[BUFSIZE] = "cs_fifo";
int server_client_fifo;
char sc_fifo[BUFSIZE];
sprintf(sc_fifo, "sc_fifo_%d", getpid());
struct sent *sent;
mkfifo(sc_fifo, 0777);
while(1) {
printf("Write the name of the file: ");
scanf("%s", name);
printf("1111\n");
client_server_fifo = open(cs_fifo, O_WRONLY);
printf("2222\n");
printf("%s", name);
printf("%s", cs_fifo);
sent->name = name;
sent->fifo = cs_fifo;
printf("%s", name);
printf("%s", cs_fifo);
write(client_server_fifo, sent, sizeof(*sent));
server_client_fifo = open(sc_fifo, O_RDONLY);
if (read(server_client_fifo, recieved, sizeof(recieved)) == -1) {
printf("An error ocurred.\n");
} else {
printf("First line of the file: \n%s\n", recieved);
close(client_server_fifo);
close(server_client_fifo);
}
memset(recieved, 0, sizeof(recieved));
}
return 0;
}
And here's server.c :
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#define BUFSIZE 512
struct sent {
char name[BUFSIZE];
char fifo[BUFSIZE];
};
int main()
{
int client_server_fifo;
char cs_fifo[BUFSIZE] = "cs_fifo";
int server_client_fifo;
char sc_fifo[BUFSIZE];
struct sent *sent;
char name[BUFSIZE];
char line[BUFSIZE];
FILE *file;
printf("Server running...\n");
mkfifo(cs_fifo, 0777);
while (1)
{
client_server_fifo = open(cs_fifo, O_RDONLY);
read(client_server_fifo, sent, sizeof(*sent));
strcpy(name, sent->name);
strcpy(sc_fifo, sent->fifo);
if((file = fopen(name, "r")) != NULL) {
printf("%s\n", name);
fgets(line, BUFSIZE, file);
printf("%s\n", name);
}
server_client_fifo = open(sc_fifo, O_WRONLY);
write(server_client_fifo, line, strlen(line));
memset(name, 0, sizeof(name));
memset(line, 0, sizeof(line));
close(client_server_fifo);
}
return 0;
}
Why does this happen?
The program has undefined behavior because in gthis statement
sprintf(sc_fifo, "sc_fifo_%d", getpid());
you are trying to change a string literal pointed to by the pointer sc_fifo.
char *cs_fifo = "cs_fifo";
When you declare a pointer to a string literal always declare them with the qualifier const. In this case you will get ban error at compilation time if you will tray to change a string literal.
Also you are using uninitialized pointer sent
struct sent *sent;
in this statement
read(client_server_fifo, sent, sizeof(*sent));
There are other errors. For example arrays do not have the assignment operator. So these statements in client.c
sent->name = name;
sent->fifo = cs_fifo;
are incorrect.
My program is supposed to take text from a file given in the command line change it to uppercase and store it in another file.
It works except the output file has a whole bunch of garbage after the converted text. Thank you
Edit: I changed my read to check for 0 bytes and used ret_in to write per Pyjamas it still pulls two or three garbage values. It's definitely read getting the garbage because when I output the buffer before converting it's there.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#define BUF_SIZE 500
int main(int argc, char* argv[]){
char buffer[BUF_SIZE];
int ret_in;
char inputf[100],outputf[100],txt[4],up[3];
// Takes input and adjusts it to the correct file type.
strcpy(inputf,argv[1]);
strcpy(outputf,argv[1]);
strcat(outputf,".up");
printf("%s\n",outputf);
strcat(inputf,".txt");
printf("%s\n",inputf);
int output, input,wrt;
int total;
//opens input file
input=open(inputf, O_RDONLY);
if (input == -1) {
printf("Failed to open file\n");
exit(1);
}
ret_in = read(input,buffer,BUF_SIZE);
total = ret_in;
// output to console
while (ret_in!= 0) {
// printf("%s\n", buffer);
ret_in = read(input,buffer,BUF_SIZE);
total += ret_in;
}
//ret_in= read(input,&buffer,BUF_SIZE);
puts(buffer);
close(input);
int i = 0;
while(buffer[i]) {
buffer[i] = toupper(buffer[i]);
i++;
}
// output buffer in console
puts(buffer);
//output filename in console
printf("%s\n",outputf);
// Opens or creates output file with permissions.
output = open(outputf, O_CREAT| S_IRUSR | O_RDWR);
if (output == -1) {
printf("Failed to open or create the file\n");
exit(1);
}
// write to output file
wrt = write(output, buffer,total);
close(output);
return 0;
}
Because you read ret_in bytes from file, but you write BUF_SIZE to the file, you should write ret_in bytes to the file. You are not supposed to read BUF_SIZE bytes from file every time, it depends, right?
write(output, buffer,BUF_SIZE);//wrong
write(output, buffer,ret_in); //right
I'm trying to write a C program, that make user able to write stuff in a file. My Problem is that after making and running the program the file stay empty ?? any idea how can I solve this.
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
// the user should give a file to write the file
int main (int argc , char**argv)
{
int fd; // file descriptor
char ret; // the character
int offset;
if(argc != 2) {
printf("You have to give the name or the path of the file to work with \n");
printf("Exiting the program \n")
return -1;
}
fd = open (argv[1], O_WRONLY/*write*/|O_CREAT/*create if not found */, S_IRUSR|S_IWUSR/*user can read and write*/);
if (fd == -1) {
printf("can'T open the file ");
return -1;
}
printf("At wich position you want to start ");
scanf("%d",&offset);
lseek(fd,offset,SEEK_SET);
while(1) {
ret = getchar();
if(ret == '1') {
printf("closing the file");
close (fd);
return 1;
}
else
write (fd,red, sizeof(char));
}
return 0;
}
thanks in advance for you help.
I have made some changes,this should work:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
int main (int argc , char**argv)
{
int fd; // file descriptor
char ret; // the character
int offset;
if(argc != 2){
printf("You have to give the name or the path of the file to work with \n");
printf("Exiting the program \n"); **//There was ';' missing here**
return -1;
}
fd = open (argv[1], O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR);
if (fd == -1) {
printf("can'T open the file ");
return -1;
}
printf("At wich position you want to start ");
scanf("%d",&offset);
lseek(fd,offset,SEEK_SET);
while(1){
ret = getchar();
if(ret == '1'){
printf("closing the file");
close (fd);
return 1;
}
else
write (fd,&ret, sizeof(char)); **//red has been changed to &ret**
}
return 0;
}
One error I can notice, the call of write function:
write (fd,red, sizeof(char));
should be:
write (fd, &red, sizeof(char));
You forgot & before red, write need address.
syntax of write: int write( int handle, void *buffer, int nbyte );
This will cause an undefined behavior in your code at run time
Edit: in write function you are using red that is not defined, I think it should be ret variable in your code. correct it as write (fd, &ret, sizeof(char));
second, you forgot ; after printf("Exiting the program \n") in if, but I also think its mistake while posting question as you says you are getting run time error.
side note: If you are using gcc compiler then you can use gcc -Wall -pedantic to generate warnings
It should be:
write (fd,&ret, sizeof(char));
write takes the pointer to the memory position, and since ret is a single char, you need to pass a pointer to it.