My program changes first letter of each word to uppercase in a .txt file.
I enter the address of file.this program save a word as a character array named "word".it changes the first cell of array to uppercase.then counts the letters of that word and and moves back to first letter of the word.then it writes the new word in file.
But it dose not work correctly!!!
#include <iostream>
#include <stdio.h>
using namespace std;
int main ()
{
int t=0, i=0,j=0;
char word[5][20];
FILE *f;
char adres[20];
cin >> adres; // K:\\t.txt
f=fopen(adres,"r+");
{
t=ftell(f);
cout << t<<"\n";
fscanf(f,"%s",&word[i]);
word[i][0]-=32;
for (j=0;word[i][j]!=0;j++){}
fseek(f,-j,SEEK_CUR);
fprintf(f,"%s",word[i]);
t=ftell(f);
cout << t<<"\n";
}
i++;
{
fscanf(f,"%s",&word[i]);
word[i][0]-=32;
for (j=0;word[i][j]!=0;j++){}
fseek(f,-j,SEEK_CUR);
fprintf(f,"%s",word[i]);
t=ftell(f);
cout << t<<"\n";
}
return 0;
}
and the file is like:
hello kami how are you
the answer is that:
Hello kaAmihow are you
I think , this is what you need.
#include<iostream>
#include<cstring>
#include<fstream>
using namespace std;
void readFile()
{
string word;
ifstream fin;
ofstream fout;
fin.open ("read.txt");
fout.open("write.txt");
if (!fin.is_open()) return;
while (fin >> word)
{
if(word[0]>='a' && word[0]<='z')
word[0]-=32;
fout<< word << ' ';
}
}
int main(){
readFile();
return 0;
}
This looks like homework.
Don't try to read and write in the same file. Use different files (in.txt & out.txt, for instance). You may delete & rename the files at end.
Use c++ streams.
Read one character at a time.
Divide your algorithm in three parts:
Read & write white-space until you find a non-white-space character.
Change the character to uppercase and write it.
Read and write the rest of the word.
Here it is a starting point:
#include <fstream>
#include <locale>
int main()
{
using namespace std;
ifstream is( "d:\\temp\\in.txt" );
if ( !is )
return -1;
ofstream os( "d:\\temp\\out.txt" );
if ( !os )
return -2;
while ( is )
{
char c;
while ( is.get( c ) && isspace( c, locale() ) )
os.put( c );
is.putback( c );
// fill in the blanks
}
return 0;
}
[EDIT]
Your program has too many problems.
It is not clear what you're trying to do. You probably want to capitalize each word.
scanf functions skip white-spaces in front of a string. If the file contains " abc" (notice the white space in front of 'a') and you use fscanf, you will get "abc" - no white-space.
Subtracting 32 from a character does not necessarily convert it to a capital letter. What if it is a digit, not a letter? Instead you should use toupper function.
etc.
[EDIT] One file & c style:
#include <stdio.h>
#include <ctype.h>
int main()
{
FILE* f = fopen( "d:\\temp\\inout.txt", "r+b" );
if ( !f )
return -1;
while ( 1 )
{
int c;
//
while ( ( c = getc( f ) ) && isspace( c ) )
;
if ( c == EOF )
break;
//
fseek( f, -1, SEEK_CUR );
putc( toupper( c ), f );
fseek( f, ftell( f ), SEEK_SET ); // add this line if you're using visual c
//
while ( ( c = getc( f ) ) != EOF && !isspace( c ) )
;
if ( c == EOF )
break;
}
fclose( f );
return 0;
}
Related
So I am making a small program.You enter a string then my program outputs the string except where a was a consonant is now a "C" and for vowels a "V".Why does it output wrong when I enter "Elicopter" and maybe other words?
#include <iostream>
#include <string>
using namespace std;
int main()
{
const char con[]={'b','c','d','f','g','h','i','j','k','l','m','n','p','q','r','s','t','v','w','x','y','z','B','C','D','F','G','H','I','J','K','L','M','N','P','Q','R','S','T','V','W','X','Y','Z'};
const char vow[]={'a','e','i','o','u','A','E','I','O','U'};
const char car[]={'!','#','#','$','%','^','&','*','?','+','-','_','0','1','2','3','4','5','6','7','8','9'};
int scon=sizeof(con)/sizeof(con[0]);
int svow=sizeof(vow)/sizeof(vow[0]);
int scar=sizeof(car)/sizeof(car[0]);
string x;
int i,j;
getline(cin,x);
for(i=0;i<x.length();i++){
if(x[i]==' '){
cout<<" ";
}
else{
for(j=0;j<scon;j++){
if(x[i]==con[j]){
cout<<"C";
break;
}
}
for(j=0;j<svow;j++){
if(x[i]==vow[j]){
cout<<"V";
break;
}
}
for(j=0;j<scar;j++){
if(x[i]==car[j]){
cout<<x[i];
break;
}
}
}
}
return 0;
}
I am sorry my code is a mess.
Aside from the obvious already pointed out by #1201ProgramAlarm ('i' being in the list of consonants), there is lots of very unidiomatic code in there -- the way you would code in C, and rather low quality C at that (no offense).
While no code is ever perfect, perhaps you might benefit from having a look at the same (well, a pretty similar...) program, written in actual C++. Just to get an idea what you could do.
#include <iostream>
#include <string>
#include <string_view>
#include <locale>
// "using namespace" is a habit that tends to get in the way
// once you start including headers from multiple namespaces,
// so while it has its place in quick one-shots, personally I
// got into the habit of fully qualifying.
int main()
{
// This is, of course, very non-international, but I will
// let this slide and not drag the ICU library into this...
std::string_view const consonants { "bcdfghjklmnpqrstvwxyz" };
std::string_view const vowels { "aeiou" };
std::string input;
// while instead of if allows you to make multiple lines of
// input. <Ctrl>-D to end the program (<Ctrl>-Z <Enter> on
// Windows).
while ( getline( std::cin, input ) )
{
// Range-For eliminates the need for loop counters / iterators
for ( auto const c : input )
{
if ( consonants.find( std::tolower( static_cast<unsigned char>( c ) ) ) != std::string::npos )
{
std::cout << 'C';
}
else if ( vowels.find( std::tolower( static_cast<unsigned char>( c ) ) ) != std::string::npos )
{
std::cout << 'V';
}
else if ( std::isprint( static_cast<unsigned char>( c ) ) )
{
// Not exactly the same as your list of digits
// and punctuation, but similar, and showing the
// use of character types. isprint() is also true
// for ' '.
std::cout << c;
}
}
// std::endl ensures a flush of the write buffer
std::cout << std::endl;
}
}
I am pretty new to Arduino business. How do I read the last line from a SD Card? With following code snippet I can read the first line (all characters before "\n"). Now I would like to include a "backwards" statement (or something).
My code so far:
#include <SD.h>
#include <SPI.h>
File SD_File;
int pinCS = 10;
char cr;
void setup() {
Serial.begin(9600);
SD.begin();
SD_File = SD.open("test.txt", FILE_WRITE);
SD_File.println("hello");
SD_File.close();
SD_File = SD.open("test.txt");
while(true){
cr = SD_File.read();
if((cr == '\n') && ("LAST LINE?"))
break;
Serial.print(cr);
}
SD_File.close();
}
void loop() {
}
Your help is much appreciated.
Since you are technically opening text files, you could use seekg to jump to the end of the file and read the last line, as described in this answer.
If this is not helpful, adding a bit more context and an example file would help us understand your question better.
I am not sure I understood your question.
"How do I implement seekg?" There is not seekg. There is however, a seek.
This is the documentation page for the SD library. In the right side of the page there is a list of all File class methods (seek among others).
" How do I read the last line..." There is no line reading in your code. If you just want to go to the end of file use: SD_File.seek( SD_File.size() ); If you want to read the last line, the simplest way is to write a getline function and read the whole file line by line until end. Assuming MAX_LINE is large enough and getline returns zero on success:
//...
char s[ MAX_LINE ];
while ( getline( f, s, MAX_LINE , '\n' ) == 0 )
;
// when reaching this point, s contains the last line
Serial.print( "This is the last line: " );
Serial.print( s );
Here's a getline idea (no warranty - not tested):
/*
s - destination
count - maximum number of characters to write to s, including the null terminator. If
the limit is reached, it returns -2.
delim - delimiting character ('\n' in your case)
returns:
0 - no error
-1 - eof reached
-2 - full buffer
*/
int getline( File& f, char* s, int count, char delim )
{
int ccount = 0;
int result = 0;
if ( 0 < count )
while ( 1 )
{
char c = f.peek();
if ( c == -1 )
{
f.read(); // extract
result = -1;
break; // eof reached
}
else if ( c == delim )
{
f.read(); // extract
++ccount;
break; // eol reached
}
else if ( --count <= 0 )
{
result = -2;
break; // end of buffer reached
}
else
{
f.read(); // extract
*s++ = c;
++ccount;
}
}
*s = '\0'; // end of string
return ccount == 0 ? -1 : result;
}
I have a file with 9 words and i have to store each word into the char array of 9 pointers but i keep getting an error message. I cannot use vectors!
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
char *words[9];
ifstream inStream;
inStream.open("sentence.txt");
if (inStream.fail())
{
cout << "Input file opening failed.\n";
exit(1);
}
for ( int i = 0; i < 10; i++)
{
inStream >> words[i];
}
inStream.close();
return 0;
}
The declaration
char *words[9];
declares a raw array of pointers. This array is not initialized so the pointers have indeterminate values. Using any of them would be Undefined Behavior.
Instead you want
vector<string> words;
where vector is std::vector from the <vector> header, and string is std::string from the <string> header.
Use the push_back member function to add strings to the end of the vector.
Also you need to move the close call out of the loop. Otherwise it will close the file in the first iteration.
This approach gives the code (off the cuff, disclaimer...)
#include <fstream>
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main()
{
vector<string> words;
ifstream inStream;
inStream.open("sentence.txt");
for ( int i = 0; i < 10; i++)
{
string word;
if( inStream >> word )
words.push_back( word );
}
inStream.close();
}
If you can't use std::string and std::vector then you need to initialize the array of pointers, and make sure that you don't read more into the buffers than there's room for.
The main problem here is that >> is unsafe for reading into a raw array given by a pointer. It doesn't know how large that array is. It can easily lead to a buffer overrun, with dire consequences.
And so this gets a bit complicated, but it can look like this:
#include <ctype.h> // isspace
#include <fstream>
#include <iostream>
#include <locale.h> // setlocale, LC_ALL
#include <stdlib.h> // EXIT_FAILURE
using namespace std;
void fail( char const* const message )
{
cerr << "! " << message << "\n";
exit( EXIT_FAILURE );
}
void readWordFrom( istream& stream, char* const p_buffer, int const buffer_size )
{
int charCode;
// Skip whitespace:
while( (charCode = stream.get()) != EOF and isspace( charCode ) ) {}
int n_read = 0;
char* p = p_buffer;
while( n_read < buffer_size - 1 and charCode != EOF and not isspace( charCode ) )
{
*p = charCode; ++p;
++n_read;
charCode = stream.get();
}
*p = '\0'; // Terminating null-byte.
if( charCode != EOF )
{
stream.putback( charCode );
if( not isspace( charCode ) )
{
assert( n_read == buffer_size - 1 ); // We exceeded buffer size.
stream.setstate( ios::failbit );
}
}
}
int main()
{
static int const n_words = 9;
static int const max_word_length = 80;
static int const buffer_size = max_word_length + 1; // For end byte.
char *words[n_words];
for( auto& p_word : words ) { p_word = new char[buffer_size]; }
ifstream inStream{ "sentence.txt" };
if( inStream.fail() ) { fail( "Input file opening failed." ); }
setlocale( LC_ALL, "" ); // Pedantically necessary for `isspace`.
for( auto const p_word : words )
{
readWordFrom( inStream, p_word, buffer_size );
if( inStream.fail() ) { fail( "Reading a word failed." ); }
}
for( auto const p_word : words ) { cout << p_word << "\n"; }
for( auto const p_word : words ) { delete[] p_word; }
}
You never allocate any memory for your char* pointers kept in the array.
The idiomatic way to write a c++ code would be:
#include <iostream>
#include <fstream>
#include <vector>
int main() {
std::vector<std::string> words(9);
std::ifstream inStream;
inStream.open("sentence.txt");
for ( int i = 0; inStream && i < 9; i++) {
inStream >> words[i];
}
}
The inStream.close() isn't necessary, and even wrong inside the loop. The std::istream will be closed automatically as soon the variable goes out of scope.
There are a few problems with your code.
char *words[9];
This allocates space for 9 pointers, not nine strings. Since you don't know how big the strings are you have two choices. You can either "guess" how much you'll need and limit the inputs accordingly, or you can use dynamic memory allocation (malloc or new) to create the space you need to store the strings. Dynamic memory would be my choice.
for ( int i = 0; i < 10; i++)
This loop will execute on words[0] through words[9]. However, there is no words[9] (that would be the tenth word) so you'll overwrite memory that you have not allocated
inStream >> words[i];
This will send your input stream to memory that you don't "own". You need to allocate space for the words to live before capturing them from the input stream. To do this correctly, you'll need to know how much space each word will need so you can allocate it.
you could try something like this:
int main()
{
char *words[9];
char tempInput[256]; // space to capture the input, up to a maximum size of 256 chars
ifstream inStream;
inStream.open("sentence.txt");
if (inStream.fail())
{
cout << "Input file opening failed.\n";
exit(1);
}
for ( int i = 0; i < 9; i++)
{
//Clear the input buffer
memset(tempInput, 0, 256);
//Capture the next word
inStream >> tempInput;
//allocate space to save the word
words[i] = new char(strlen(tempInput));
//Copy the word to its final location
strcpy(words[i], tempInput)
}
inStream.close();
return 0;
}
Is there any way i can write a method which returns all the pointer variable names used in the C++ file.
For ex: c++ file (abc.cpp)
.......
//some code here
.....
emp* emp1 = do_something();
int a = 10;
student* std1 = getdata();
...
..
When I parse this file (abc.cpp ) i should get two variables in output.
output
emp1
std1
Is there any way some built in methods/procedure which tells the type of variable and list only pointer type of variables.
Thanks
There's no built in method or procedure to do this in C++ itself. However, you could find an open source c++ parser and use it to do this.
There's a stack overflow discussion on this: Good tools for creating a C/C++ parser/analyzer
There is no such thing. You have to open the file and parse it's contents to find out what you want to find out. You could use Boost Regular Expressions to do this.
Sure you can't do that with standard C++ tools. My algorythm to do the job would be something like:
Read the whole .cpp into std::string:
std::ifstream ifs("filename.cpp");
std::string str((std::istreambuf_iterator<char>(ifs)),
std::istreambuf_iterator<char>());
Find all strings in that string which placed between '*' and '=' symbols and place them in array std::vector - sure it's very rough algorythm but would suite for simple task;
For every string in this array delete all white spaces.
Print all array elements.
Here is the code:
#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
#include <vector>
#include <set>
#include <cctype>
using namespace std;
vector< string > types;
set< string > names;
int main() {
types.push_back( "int" );
types.push_back( "char" );
types.push_back( "float" );
types.push_back( "double" );
types.push_back( "bool" );
types.push_back( "unsigned" );
types.push_back( "long" );
types.push_back( "short" );
types.push_back( "wchar_t" );
// ect
fstream in( "input.cpp", fstream::in );
string row;
string tmp;
while( in >> tmp ) {
if( tmp == "struct" || tmp == "class" ) {
in >> tmp;
string::iterator it = find( tmp.begin(), tmp.end(), '{' );
tmp.erase( it, tmp.end() );
types.push_back( tmp );
}
row += tmp;
}
for( int i=0; i<types.size(); ++i ) {
int it=-1;
while( ( it=row.find( types[ i ], it+1 ) ) ) {
if( it == -1 ) break;
int spos;
for( spos=it; row[ spos ] != '*'; ++spos );
spos++;
string ptr;
while( ( isalnum( ( int )row[ spos ] ) || row[ spos ] == '_' ) && spos < row.size() ) {
ptr += row[ spos ];
spos++;
}
names.insert( ptr );
}
}
for( set< string >::iterator i=names.begin(); i!=names.end(); ++i ) {
cout << *i << " ";
}
return 0;
}
What I basically do, is that I put the whole input program into a row, without spaces, then check for user defined structs or classes, which I insert into the types vector, and finally I search for each type if there exists something in the form <type>* in the row. Then, I print it.
I want to read line by line from a file in C or C++, and I know how to do that when I assume some fixed size of a line, but is there a simple way to somehow calculate or get the exact size needed for a line or all lines in file? (Reading word by word until newline is also good for me if anyone can do it that way.)
If you use a streamed reader, all this will be hidden from you. See getline. The example below is based from the code here.
// getline with strings
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main () {
string str;
ifstream ifs("data.txt");
getline (ifs,str);
cout << "first line of the file is " << str << ".\n";
}
In C, if you have POSIX 2008 libraries (more recent versions of Linux, for example), you can use the POSIX getline() function. If you don't have the function in your libraries, you can implement it easily enough, which is probably better than inventing your own interface to do the job.
In C++, you can use std::getline().
Even though the two functions have the same basic name, the calling conventions and semantics are quite different (because the languages C and C++ are quite different) - except that they both read a line of data from a file stream, of course.
There isn't an easy way to tell how big the longest line in a file is - except by reading the whole file to find out, which is kind of wasteful.
I would use an IFStream and use getline to read from a file.
http://www.cplusplus.com/doc/tutorial/files/
int main () {
string line;
ifstream myfile ("example.txt");
if (myfile.is_open())
{
while ( myfile.good() )
{
getline (myfile,line);
cout << line << endl;
}
myfile.close();
}
else cout << "Unable to open file";
return 0;
}
You can't get the length of line until after you read it in. You can, however, read into a buffer repeatedly until you reach the end of line.
For programming in c, try using fgets to read in a line of code. It will read n characters or stop if it encounters a newline. You can read in a small buffer of size n until the last character in the string is the newline.
See the link above for more information.
Here is an example on how to read an display a full line of file using a small buffer:
#include <stdio.h>
#include <string.h>
int main()
{
FILE * pFile;
const int n = 5;
char mystring [n];
int lineLength = 0;
pFile = fopen ("myfile.txt" , "r");
if (pFile == NULL)
{
perror ("Error opening file");
}
else
{
do
{
fgets (mystring , n , pFile);
puts (mystring);
lineLength += strlen(mystring);
} while(mystring[strlen ( mystring)-1] != '\n' && !feof(pFile));
fclose (pFile);
}
printf("Line Length: %d\n", lineLength);
return 0;
}
In C++ you can use the std::getline function, which takes a stream and reads up to the first '\n' character. In C, I would just use fgets and keep reallocating a buffer until the last character is the '\n', then we know we have read the entire line.
C++:
std::ifstream file("myfile.txt");
std::string line;
std::getline(file, line);
std::cout << line;
C:
// I didn't test this code I just made it off the top of my head.
FILE* file = fopen("myfile.txt", "r");
size_t cap = 256;
size_t len = 0;
char* line = malloc(cap);
for (;;) {
fgets(&line[len], cap - len, file);
len = strlen(line);
if (line[len-1] != '\n' && !feof(file)) {
cap <<= 1;
line = realloc(line, cap);
} else {
break;
}
}
printf("%s", line);
getline is only POSIX, here is an ANSI (NO max-line-size info needed!):
const char* getline(FILE *f,char **r)
{
char t[100];
if( feof(f) )
return 0;
**r=0;
while( fgets(t,100,f) )
{
char *p=strchr(t,'\n');
if( p )
{
*p=0;
if( (p=strchr(t,'\r')) ) *p=0;
*r=realloc(*r,strlen(*r)+1+strlen(t));
strcat(*r,t);
return *r;
}
else
{
if( (p=strchr(t,'\r')) ) *p=0;
*r=realloc(*r,strlen(*r)+1+strlen(t));
strcat(*r,t);
}
}
return feof(f)?(**r?*r:0):*r;
}
and now it's easy and short in your main:
char *line,*buffer = malloc(100);
FILE *f=fopen("yourfile.txt","rb");
if( !f ) return;
setvbuf(f,0,_IOLBF,4096);
while( (line=getline(f,&buffer)) )
puts(line);
fclose(f);
free(buffer);
it works on windows for Windows AND Unix-textfiles,
it works on Unix for Unix AND Windows-textfiles
Here is a C++ way of reading the lines, using std algorithms and iterators:
#include <iostream>
#include <iterator>
#include <vector>
#include <algorithm>
struct getline :
public std::iterator<std::input_iterator_tag, std::string>
{
std::istream* in;
std::string line;
getline(std::istream& in) : in(&in) {
++*this;
}
getline() : in(0) {
}
getline& operator++() {
if(in && !std::getline(*in, line)) in = 0;
}
std::string operator*() const {
return line;
}
bool operator!=(const getline& rhs) const {
return !in != !rhs.in;
}
};
int main() {
std::vector<std::string> v;
std::copy(getline(std::cin), getline(), std::back_inserter(v));
}