I/O redirection - c

#include<stdio.h>
#include<stdlib.h>
int main()
{
int i;
for(i=1; i<=255; i++)
{
printf("%d %c\n",i,i);
}
}
Hey i am working my way out from i/o redirection, and i got stuck in outputting ascii table from command prompt i done this.
C:\New folder\practice> main.exe > temp.txt
C:\New folder\practice> type temp.txt
and after hitting enter (after type temp.txt) it only outputs first 26 numbers. My question is why?
Also can someone explain me how to just copy the code into text file using redirection I know how to do using FILE I/O.

Because you're using MS-DOS... er MS WinDOS, and there ASCII number 26/^Z is the end-of-text-file mark.
The feature exists so that the environment is compatible with the CP/M operating system of the early 1970s, in case you'd need to use some files that originate from that. As you've noticed, only type works like that, but more would display more... (no pun intended).
No kidding.

It is very dangerous to write non ASCII characters in a text stream. 0x10 is \n and and can be changed into the underlying system end of line which is \r\n on Windows.
The correct way is to open a file in binary mode:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int i;
FILE *fd = fopen("temp.txt", "wb");
if (NULL == fd) {
perror("Error opening file");
return 1;
}
for(i=1; i<=255; i++)
{
fprintf(fd, "%d %c\n",i,i);
}
fclose(fd);
return 0;
}
That being said, commands expecting text files may stop when they read a SUB control character (CtrlZ code 0x1A), which is you current problem...

Related

Error with binary-writting mode with C, on Windows?

I am learning how to write a simple CGI page with C language. I tried with Apache on both Linux and Windows. I compiled my scripts on 2 different computers that run different OSes.
Firstly, I created a simple CGI page for getting a static plain-text content:
#include
int main()
{
FILE *fp = fopen("plain_text.txt", "r"); // text-mode only.
if (fp)
{
int ch;
printf("content-type: text/plain\n\n");
while ((ch = fgetc(fp)) != EOF)
{
printf("%c", ch);
}
fclose(fp);
}
return 0;
}
I compiled it into an executable and put it in cgi-bin directory. When I browse it with my web-browser, it returns the plain-text content correctly (both Linux and Windows).
Then, I modified above script for getting a simple JPEG content.
(I understand that: every JPEG picture is a binary file)
#include
int main()
{
FILE *fp = fopen("cat_original.jpg", "rb"); // with binary-mode.
if (fp)
{
int ch;
printf("content-type: image/jpg\n\n");
while (((ch = fgetc(fp)) != EOF) || (!feof(f1))) // can read whole content of any binary file.
{
printf("%c", ch);
}
fclose(fp);
}
return 0;
}
I compiled it into an executable and put it in cgi-bin directory, too.
I can get the correct returned-image with Linux compiled-executable files; but, the Windows does not.
To understand the problem, I downloaded the returned-image with Windows compiled-execute files.
(I named this image: cat_downloaded_windows.jpg)
Then, I used VBinDiff for compare 2 images: cat_original.jpg (68,603 bytes) and cat_downloaded_windows.jpg (68,871 bytes).
There are many lines in cat_downloaded_windows.jpg (like the row I marked) have a character which cat_original.jpg does not have.
VBinDiff
So, I guess that the Windows OS causes the problem (Windows add some characters automatically, and Linux does not)
(Apache and web-browsers do not cause problem)
So, I posted this topic into StackOverflow for getting your helps. I have 2 questions:
Is there any problem with the printf("%c", ch); (in my script) on Windows?
Is there any way to print binary content into stdout, both Linux and Windows?
I am learning programming myself, and this is the first time I ask on StakOverflow.
So, if my question is not clear, please comment below this question; I will try to explain it more.
Thank you for your time!
When you use printf() to write to standard output, it is working in text mode, not binary mode, so every time your program encounters a newline \n in the JPEG file, it writes \r\n on Windows, which corrupts the JPEG file.
You'll need to know how to put standard output into binary mode and you'll need to ensure that you generate \r\n in place of \n in the headers.
The MSDN documentation says you can use _setmode(), and shows an example (setting stdin instead of stdout):
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
int main(void)
{
int result;
// Set "stdin" to have binary mode:
result = _setmode(_fileno(stdin), _O_BINARY);
if (result == -1)
perror("Cannot set mode");
else
printf("'stdin' successfully changed to binary mode\n");
}

How can I verify in my C program that four terminals are currently open?

So I'm going to preface this by saying that this is for a homework project in my class. I am supposed to determine that the user opened four terminal windows before running the program, and I have to do this by determining if I can open four terminal number buffers from /dev/pts/ as read-only. I then have to save these first four buffers so I can open them again to write to the terminals. I know how to open the files with fopen but my issue is even the terminals that aren't open anymore still show up and are accessible. I know that its pretty frowned upon to ask for homework help but I've been working at this for hours and I don't want it written for me I just want some direction. How can I check that there are four terminals open using the method that I have to use? Also here's my code so maybe one of y'all can see what I'm doing wrong.
#include <stdio.h>
#include <stdlib.h>
#define MAXLINE 100
int main(){
int i, ptsNum[4], ptsCount = 0;
FILE *fp;
char ptsName[20];
for(i = 0; i < 20; i++){
// Append the terminal number to the end of the buffer name
sprintf(ptsName, "/dev/pts/%d", i);
// Try to open the file
if((fp = fopen(ptsName, "r")) != NULL){
// Save the terminal number if the buffer exists
ptsNum[ptsCount] = i;
ptsCount++;
fclose(fp);
}
}
return 0;
}
Well, you try to open the terminals, but once you get them counted, you fclose(3) them, so in case you want them open, don't do the last fclose(3) at the end of the loop.

Can not open files with c

Im supposed to write a program that opens an excel file, reads the numbers on the file, multiplies them by 9.8 and the shows the answer in another excel gile.
I wrote this, and I did not get any errors in the compiler, but when I run it, it does not open any files. How do I make it open the files?
#include <stdio.h>
int main() {
FILE *archivo;
FILE *archivoSalida;
int masa;
float peso;
archivo = fopen("C:/Users/nacho/Documents/UNAM/Informatica/proyecto/archivoEntrada.txt", "r");
archivoSalida = fopen("C:/Users/nacho/Documents/UNAM/Informatica/proyecto/archivoSalida.txt", "r");
if (archivo != NULL)
{
printf("The file was opened succesully");
while (fscanf(archivo,"%d", &masa)!= EOF)
{
peso=masa*9.81;
fprintf(archivoSalida, "%f\n", peso);
}
}
else
{
printf ("Error");
}
fclose(archivo);
fclose(archivoSalida);
return 0;
}
You'll want to fopen the output file ("archivoSalida") with mode "w" (for write) instead of "r" (for read). See e.g. http://pubs.opengroup.org/onlinepubs/009695399/functions/fopen.html.
You do check if the input file could be opened (if (archivo != NULL)). Why don't you do the same for the output file?
Upon an error, you should output which error occured from errno, e.g. via perror(...). That should help in finding the actual problem.
Your file denominated by archivoSalida is opened in read mode ('r').
You should also check the return codes of read/writes functions to be sure everything happen as wanted.
The file names look Windows-ish. Is it possible that all of the forward slashes (/) that you have in both file names should really be back slashes (\)?

Discrepancy with fgetc while reading a text file

I´m beginning with C and I´m willing to understand certain conditions.
I have a text file, generated by notepad or direct via shell by echo in a windows os.
When running this the output show extra chars. What I ´m doing wrong? How I can read text files in a secure way char by char?
Using codeblocks with minggw.
file.txt:
TEST
C program
void main()
{
int i;
FILE *fp;
fp = fopen("file.txt","r");
while ((i = fgetc(fp)) != EOF)
{
printf("%c",i);
}
}
Output
 ■T E S T
Your code has issues, but the result is fine.
Your file is likely UTF-8 with a (confusingly enough) byte order mark in the beginning. Your program is (correctly) reading and printing the bytes of the BOM, which then appear in the output as strange characters before the proper text.
Of course, UTF-8 should never need a byte order mark (it's 8-bit bytes!), but that doesn't prevent some less clued-in programs from incuding one. Window's Notepad is the first program on the list of such programs.
UPDATE: I didn't consider the spacing between your letters, which of course indicate 16-bit input. That's your problem right there, then. Your C code is not reading wide characters.
Try this code
void main()
{
int c,i;
FILE *fp;
fp = fopen("file.txt","r");
while ((i = fgetc(fp)) != EOF)
{
printf("%c",i);
}
}'

Writing to FIFO file with c

I am relatively new to programming. What I am trying to accomplish is to write to a FIFO file I think its called. Basically if I am at a terminal window I can execute the command echo "0=0" > /dev/pi-blaster it will work as intended. So what I want to do is write a program that will basically execute that command for me but change the numbers between the double quotes. I know how to change the numbers with a loop I am just having trouble getting it to actually write the file. There are no errors being generated during compilation or running it simply does not function as if I were to type the command above. Like I said I am new to programming so maybe I am not even on the right path. I have included my code below:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *fp;
int i;
fp = fopen("/dev/pi-blaster", "w");
if (fp == NULL) {
printf("I couldn't open pi-blaster for writing.\n");
exit(0);
}
for (i=0; i<=10; ++i)
fprintf(fp, "echo %d=%d", i, i*i);
return 0;
}
What you are doing is writing the actual echo shell command to the file, not e.g. 0=0.
You should only do
fprintf(fp, "%d=%d\n", i, i * i);
PS. You don't need to worry about flushing the file buffers, it will be done automatically when the file is closed, and the file will be closed when the process exits (but it's considered good to explicitly close files that you open, even if it's not technically needed).

Resources