This is my code C/C++ code for writing a character to a file.
#include "mbed.h"
Serial pc(USBTX, USBRX);
char c;
char *cha = &c;
int main() {
FILE* WriteTo = fopen("/local/yourtext.txt", "w");
pc.printf("Write something and then press enter when finished...\n\r");
while (c != '\n') {
c = pc.getc();
pc.printf(cha);
fputc(c, WriteTo);
}
fclose(WriteTo);
pc.printf("File write successfull.\n\r");
}
The problem is that it doesn't work on my LPC1768. It only takes in one character and then I am unable to type anymore. I tried some other ways but none of the ways I tried allowed me to write to a file.
I'd like to also know if getc() empties out after I use putc. Does it have a limitation on the amount of characters I can write?
pc.printf(cha);
printf needs format argument to be null terminated char *.
But you are passing non null terminated char * thus by invoking undefined behavior.
Use:
pc.printf("%c", *cha); //Or pc.printf("%c", c);
Related
This is my code to bind a text file content to a linked list in C, the read job is ok but its made an error in fclose(f), Stack around the variable 'st' was corrupted. I don't understand it, how can I fix it?
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <iostream>
using namespace std;
struct Nut
{
char Tu[7];
Nut * Tiep;
};
Nut TD[26];
Nut *first;
void AddFirst(Nut *q, Nut *&first)
{
Nut *p;
p = new Nut;
if (first == NULL)
{
first = q;
return;
}
for (p = first; p->Tiep != NULL; p = p->Tiep)
p->Tiep = q;
}
void ReadData(Nut *ds[], int &n)
{
n = 0;
char old = '0';
FILE *f;
Nut *Tam;
Nut *Tu;
f = fopen("TD.txt", "r");
int dem = -1;
if (f == NULL)
cout << "File rong !!!";
else
{
while (!feof(f) == 1)
{
char st[8] = "";
fscanf(f, "%s", st);
Tam = new Nut();
strcpy(Tam->Tu, st);
char c = st[0];
if (c != old){
dem++;
ds[dem] = new Nut();
n++;
}
AddFirst(Tam, ds[dem]);
}
}
fclose(f);
}
Update 1:
Sorry, I must do it in C, but I use Visual C++, the final environment is C
data file, td.txt
ACCEPT
ADULT
APART
AUGUST
BACK
BAD
BOY
BREAK
CAT
CHEF
CHICKEN
COWBOY
CRY
DAD
DESIGN
DIE
DRAW
EAT
EMPTY
ERROR
EXPLORE
FAN
FELL
FESTIVAL
FULL
GAS
GIVE
GRAPHIC
You use fscanf to read the strings into an array containing 8 characters, which means you can read string having 7 characters at most because the last character must be the special string-termination character '\0'.
However, in the input you have e.g. the string
FESTIVAL
which is exactly 8 characters, but needs 9 characters including the terminator. This will cause fscanf to write beyond the bounds of the array st.
What's worse is that you then copy this 9-character data into an array of only 7 characters, once again writing out of bounds.
Writing out of bounds of an array leads to undefined behavior, and makes your whole program ill-formed.
The most obvious problem: you're reading into a buffer of
8 char, but some of your data requires 9 (don't forget the trailing
'\0'); you then strcpy this into a buffer of 7 char. For the
input you give, you need buffers of at least 9 characters. You also
want to provide a width argument in the format of fscanf, in order to
avoid overwriting the buffer regardless of the input. (In fact, you
probably want to use fgets, to read line by line, with a very large
buffer, and then check that 1) you've actually read to the end of the
line (the last character should be a '\n'), and 2) that the word in
the line has at most one less characters than the size of your buffer.
(Obviously, this would all be significantly simpler in C++.)
I am trying to write a program will open a regular type file (binary or text/ASCII, read every byte in the file and write both the ASCII hex value for that byte as well as it’s printable (human-readable) character (characters, digits, symbols) to standard output. I am now just trying to let the user pick the file.
#include <stdio.h>
#include<stdlib.h>
FILE *file;
int main(int argc, char *argv[ ]){
int a;
int modified = 1;//1 means unmodified, 0 means modified
if(argc > 2){//writes to std error output
return 25;
}
if(argc == 2){// if there is 1 argument open it and read it
file = fopen(argv[1], "rt");
if(file == NULL){//cant open file. return error code 15
fprintf(stderr, "cant opent file %s \nerror code 15 \n", argv[1]);
return 15;
}
a = getc(file);
}else// get characters from stdin if no arguments
a = getchar();
char *buffer = malloc(200);
int j = 0;// buffer index helper
while( a != EOF){//reads character by character until EOF
if(j > 200){
j =0;
// fprintf(stderr,"error error, buffer overflow. \n error code 35 \n"); // send error to stderrl
// return 35;
}
I am getting errors though:
error: invalid conversion from `void*' to `char*'
xsd.cpp:30: error: expected `}' at end of input
xsd.cpp:30: error: expected `}' at end of input
The major problem is that you write C in a C++ program. C and C++ are similar, due to C++ inheriting from C, but they are ultimately different languages. For example, C++ have a harder and tougher type system, so you can't e.g. have implicit cast from void * to other pointer types like you can in C. In C++ you have to cast void * to the correct pointer, like e.g.
char *buffer = reinterpret_cast<char*>(malloc(200));
Even better would be to not write C code in C++, and use the C++ functionality like new/delete, the C++ input/output library, and classes like std::string for strings, etc.
Then there's of course the problem of you not having enough closing braces } at the end of the program. Did you not copy-paste all of the program?
I am trying to work out how I can print character by character the contents of a user-defined text file. I believe I have got the retrieval of the file correct but I am unsure how I can print each character.
#include <stdio.h>
#include <ctype.h>
#define ELEMENT 300
#define LENGTH 20
void main(char str[ELEMENT][LENGTH])
{
FILE *infile;
char textfile[1000];
char read_char;
int endoff;
int poswithin = 0;
int wordnum= 0;
printf("What is the name of your text file?: ");
scanf("%s", &textfile);
infile=fopen(textfile,"r");
if (infile == NULL) {
printf("Unable to open the file.");
}
else
{
endoff=fscanf(infile,"%c",&read_char);
while(endoff!=EOF);
{
This is where I believe I'm stuck. The first character is read into the variable read_char but then it doesn't seem to print anything?
if(read_char>=65&&read_char<=90 || read_char<=65)
{
str[wordnum][poswithin]=read_char;
printf("%c", read_char);
poswithin++;
}
else
{
str[wordnum][poswithin]=(char)"\n";
poswithin=0; wordnum++;
}
endoff=fscanf(infile, "%s", &read_char);
}
}
fclose(infile);
}
Typo in the format specifier to your second call to fscanf
endoff=fscanf(infile, "%s", &read_char);
should be
endoff=fscanf(infile, "%c", &read_char);
Also,
str[wordnum][poswithin]=(char)"\n";
shouldn't be casting a string literal to char and probably should be adding a NULL terminator rather than a newline:
str[wordnum][poswithin]='\0';
Finally, you shouldn't try to declare str as an argument to main.
char str[ELEMENT][LENGTH];
int main() // or int main(int argc, char* argv[])
Using fscanf with %c format specifier is overkill for reading a single character from a file.
Try fgetc to read one character. The function avoids the overhead of parsing a format specifier string and variable number of arguments.
A more efficient method is to allocate a buffer or array and read "chunks" of chars from a file, using fread. You can then scan the buffer or array. This has less function call overhead than many calls to read single bytes. Efficient buffer sizes are multiples of 512 to conform with disk drive sector sizes.
Basically I have a buffer in which i am looking for various flags to read certain fields from a binary file format. I have file read into a buffer but as i started to write code to search the buffer for the flags i immediately hit a wall. I am a C++ noob, but here is what i have:
void FileReader::parseBuffer(char * buffer, int length)
{
//start by looking for a vrsn
//Header seek around for a vrns followed by 32 bit size descriptor
//read 32 bits at a time
int cursor = 0;
char vrsn[4] = {'v','r','s','n'};
cursor = this->searchForMarker(cursor, length, vrsn, buffer);
}
int FileReader::searchForMarker(int startPos, int eof, char marker[], char * buffer)
{
int cursor = startPos;
while(cursor < eof) {
//read ahead 4 bytes from the cursor into a tmpbuffer
char tmpbuffer[4] = {buffer[cursor], buffer[cursor+1], buffer[cursor+2], buffer[cursor+3]};
if (strcmp(marker, tmpbuffer)) {
cout << "Found: " << tmpbuffer;
return cursor;
}
else {
cout << "Didn't Find Value: " << marker << " != " << tmpbuffer;
}
cursor = cursor + 4;
}
}
my header looks like this:
#ifndef __FILEREADER_H_INCLUDED__
#define __FILEREADER_H_INCLUDED__
#include <iostream>
#include <fstream>
#include <sys/stat.h>
class FileReader {
public:
FileReader();
~FileReader();
int open(char *);
int getcode();
private:
void parseBuffer(char *, int);
int searchForMarker(int, int, char[], char *);
char *buffer;
};
#endif
I would expect to get back a match for vrsn with strcmp but my result looks like this
Didn't Find Value: vrsn != vrsn
Found:
It looks like it finds it on the second pass after its passed the char array i am looking for.
Relevant hexcode
Your problem is two-fold:
strcmp returns "0" on success, not on failure. Read the documentation.
strcmp expects null-terminated strings. You say that you have chosen non-terminated char arrays because that's what your DB library uses. Well, fine. But still, you are violating the requirements of strcmp. Use strncmp instead (which takes a length argument) or, preferably, actually write C++ and start using std::vector<char> and friends.
Shouldn't that be something like int FileReader::searchForMarker(...) { .... }?
For the second query, I guess the strcmp works when it has two null terminated strings as its arguments. For example str1[]="AAA"; and str2[]="AAA"; then strcmp() would be used as
if(strcmp(str1,str2)==0) which will return 0 to indicate that they are equal. In your case, the tmpbuffer that you have created is not a null terminated string unless you add \0 in the end.So you might want to add \0 in the end of your tmpbuffer to create a string of 'v' 'r' 'n' 's'.
char vrsn[4] = {'v','r','s','n'};
Contains only the 4 characters specified. There is no room for a null character at the end.
char tmpbuffer[4] = {buffer[cursor], buffer[cursor+1], buffer[cursor+2], buffer[cursor+3]};
Contains only the 4 characters from buffer. There is no room for a null character at the end.
Eventually you call:
if (strcmp(marker, tmpbuffer)) {
The strcmp() function expects each of its parameters to end with a null character ('\0'). It wants to work with strings, which are null terminated.
Since your data is not null terminated, you probably want to use memcmp() instead of strcmp().
Also, strcmp() returns zero when its arguments are equal, so the condition in the if statement is inverted. (Zero is false, everything else is true.) The memcmp() function will also return zero when its arguments are equal.
I'm using a file system library and I'm trying to create a readline function.
int al_fgetc(ALLEGRO_FILE *f)
Introduced in 5.0.0
Read and return next byte in the given file. Returns EOF on end of file or if an error occurred.
That is the function I'm using from the library. What I want to do is += the resulting char into a std string if it is != EOF which is -1. I'm just not sure if I need to cast it to get the correct result. Will something like this do it:
bool File::readLine( std::string& buff )
{
if(eof() || !isOpen())
{
return false;
}
buff = "";
int c = 0;
while(c = al_fgetc(m_file) != EOF && c != '\n')
{
buff += (char)c;
}
return buff.length() > 0;
}
I'm going to be reading utf-8 from file so I need to make sure this works correctly.
Thanks
Yes, this will work, except you need an extra set of parentheses because the != operator has higher precedence than the = operator:
while((c = al_fgetc(m_file)) != EOF && c != '\n')
...
The only reason that fgetc returns int instead of char is that there are 257 possible return values: all 256 possible bytes, or EOF, which signals that there's no more data left in the file. It will always return either 0-255 or EOF, so it's safe to cast the return value to char or unsigned char once you've tested it for EOF.
Yeah, the only reason why they return int is because there is no "free" value in a char that could be used for the EOF signaling. Thus, checking that it's not EOF and afterwards casting it back to char is precisely what they expect you to do.
Try using feof(m_file) to check that you've hit the end of file rather than checking the character returned by fgetc. This should seperate your read loop from the eof check, so no casting is necessary.