I have an assignment that tasks me with reading from a file that contains a series of numbers in ASCII decimal format and convert them to integers. I've made a function that does this but I don't know what the numbers are in the file. How do I see open a file that contains these type of numbers? Whenever I open it in a text editor or some other program I end up with series of integer numbers. Is this what it should look like?
Thank you in advance
Assuming you have a text file containing a series of numbers in ASCII decimal format, one number per line, you can easily accomplish your task using a C program like this one:
#include <stdlib.h>
#include <stdio.h>
#define MAX_LINE_LEN (32)
int main ( int argc, char * argv[] )
{
FILE * pf;
char line[ MAX_LINE_LEN ];
/* open text file for reading */
pf = fopen( "integers.txt", "r" );
if( !pf )
{
printf("error opening input file.\n");
return 1;
}
/* loop though the lines of the file */
while( fgets( line, MAX_LINE_LEN, pf ) )
{
/* convert ASCII to integer */
int n = atoi( line );
/* display integer */
printf("%d\n", n );
}
/* close text file */
fclose( pf );
return 0;
}
/* eof */
Related
For example if the input was:
My name is Alex and
I also love coding
The correct output should be:
1:My nam
1:e is A
1:lex an
1:d
2:I also
2: love
2:coding
So far I have this
int main () {
string i;
i.substr(0,6);
while (getline(cin, i)) {
cout << i << endl;
}
}
Using ranges, what you ask is almost as easy as
auto result = view | split('\n') | transform(chunk(6));
where view represents somehow the input, | split('\n') splits that input in several lines, and | transform(chunk(6)) transforms each line by splitting it in chunks of 6 chars. The result is therefore a "range of ranges of chunks", on which you can loop with a double nested for.
Here's a full example:
#include <iostream>
#include <sstream>
#include <string>
#include <fstream>
#include <range/v3/range/conversion.hpp>
#include <range/v3/view/chunk.hpp>
#include <range/v3/view/istream.hpp>
#include <range/v3/view/split.hpp>
#include <range/v3/view/transform.hpp>
// Comment/uncomment the line below
//#define FROM_FILE
using namespace ranges;
using namespace ranges::views;
int main() {
// prepare a path-to-file or string buffer
#ifdef FROM_FILE
std::string path_to_file{"/path/to/file"};
#else
std::basic_stringbuf<char> strbuf{"My name is Alex and\nI also love coding"};
#endif
// generate an input stream from the file or the string buffer
#ifdef FROM_FILE
std::ifstream is(path_to_file);
#else
std::istream is(&strbuf);
#endif
// prevent the stream from skipping whitespaces
is >> std::noskipws;
// generate a range view on the stream
ranges::istream_view<char> view(is);
// manipulate the view
auto out_lines = view | split('\n') // split at line breaks
| transform(chunk(6)); // split each in chunks of 6
// output
int index{};
for (auto line : out_lines) {
++index;
for (auto chunk_of_6 : line) {
std::cout << index << ':'
<< (chunk_of_6 | to<std::string>)
<< std::endl;
}
}
}
First I suggest that you give your variables meaningful names. i isn't good for a variable you use to read lines from std::cin. I've changed that name to line in my example below.
You are on the right track with i.substr(0,6); but you've placed it outside of the loop where i is empty - and you don't print it.
You are also supposed to prepend each line with the line number but that part is completely missing.
You have also missed that you should print the next 6 characters of the read line on the next line until you've printed everything that you read.
Here's an example how that could be fixed:
#include <iostream>
#include <string>
int main() {
unsigned max_len = 6;
std::string line;
for(unsigned line_number = 1; std::getline(std::cin, line); ++line_number) {
// loop until the read line is empty:
while(!line.empty()) {
// print max `max_len` characters and prepend it with the line number:
std::cout << line_number << ':' << line.substr(0, max_len) << '\n';
// if the line was longer than `max_len` chars, remove the first
// `max_len` chars:
if(line.size() > max_len) {
line = line.substr(max_len);
} else { // otherwise, make it empty
line.clear();
}
}
}
}
I am looking for bash script comments from // to /* */
I got partial working
sed -i '14s/////*/' a.c
this is working like // with */ how to add */ at the end.
Originl script
#include <stdio.h>
char buffer[10] = {'0'}; // comment1
int main()
{
printf("Hello World"); // Comment2
return 0;
}
Expected file
#include <stdio.h>
char buffer[10] = {'0'}; /* comment1 */
int main()
{
printf("Hello World"); /* Comment2 */
return 0;
}
Simplest solution
Assuming the idiosyncratic spacing in the desired output shown in the question is unintentional:
sed 's%// *\(.*\)%/* \1 */%'
The keys here are:
Using % instead of / to mark the separate parts of the s/// (or s%%%) command.
Capturing the text of the comment in \(…\).
Replacing it with \1 (preceded by /* and followed by */ and single spaces.
Working on a direct copy of the data from the question, the output is:
#include <stdio.h>
char buffer[10] = {'0'}; /* comment1 */
int main()
{
printf("Hello World"); /* Comment2 */
return 0;
}
Improving the handling of spaces
There are trailing blanks after the comments — ugly! We can fix that with care:
sed 's%//[[:space:]]*\(.*[^[:space:]]\)[[:space:]]*$%/* \1 */%'
That matches zero or more spaces after the // opening the comment, and matches up to the last non-space before an optional string of spaces at the end of the line. That generates:
#include <stdio.h>
char buffer[10] = {'0'}; /* comment1 */
int main()
{
printf("Hello World"); /* Comment2 */
return 0;
}
And you can deal with all trailing white space first, which is probably a good idea anyway, using:
sed -e 's/[[:space:]]\{1,\}$//' -e 's%//[[:space:]]*\(.*\)%/* \1 */%'
which yields:
#include <stdio.h>
char buffer[10] = {'0'}; /* comment1 */
int main()
{
printf("Hello World"); /* Comment2 */
return 0;
}
That differs from the previous output by not having a space after main().
Proper comment handling is hard!
Note that this simple code can easily be confused by valid C, such as:
printf("// this is not a comment\n");
To understand C fully enough not to make that mistake is beyond sensible sed. Less seriously, it will miss some valid but implausible character sequences that are officially comments, such as:
/\
/this is a comment\
and this is also part of the comment\
even with extra spaces
and if you allow trigraphs (don't), then:
/??/
/??/
This is part of the comment started two lines before!
This sort of stuff shouldn't afflict any actual code base, but are the sorts of garbage that compiler writers have to handle correctly.
I am searching a way in SML to open a txt file whose name will be given by the user.
like in C where arv [1] is the user's filename of file.
int main (int argc, char * argv[])
{
FILE * fp;
fp = fopen(argv[1],"r");
...........
...........
}
The following code prints the desired output but it prints garbage at the end of the string. There is something wrong with the last call to MultiByteToWideChar but I can't figure out what. Please help??
#include "stdafx.h"
#include<Windows.h>
#include <iostream>
using namespace std;
#include<tchar.h>
int main( int, char *[] )
{
TCHAR szPath[MAX_PATH];
if(!GetModuleFileName(NULL,szPath,MAX_PATH))
{cout<<"Unable to get module path"; exit(0);}
char ansiStr[MAX_PATH];
if(!WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,szPath,-1,
ansiStr,MAX_PATH,NULL,NULL))
{cout<<"Unicode to ANSI failed\n";
cout<<GetLastError();exit(1);}
string s(ansiStr);
size_t pos = 0;
while(1)
{
pos = s.find('\\',pos);
if(pos == string::npos)
break;
s.insert(pos,1,'\\');
pos+=2;
}
if(!MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,s.c_str(),s.size(),szPath,MAX_PATH))
{cout<<"ANSI to Unicode failed"; exit(2);}
wprintf(L"%s",szPath);
}
MSDN has this to say about the cbMultiByte parameter:
If this parameter is -1, the function processes the entire input
string, including the terminating null character. Therefore, the
resulting Unicode string has a terminating null character, and the
length returned by the function includes this character.
If this parameter is set to a positive integer, the function processes
exactly the specified number of bytes. If the provided size does not
include a terminating null character, the resulting Unicode string is
not null-terminated, and the returned length does not include this
character.
..so if you want the output string to be 0 terminated you should include the 0 terminator in the length you pass in OR 0 terminate yourself based on the return value...
This line of code
if (sqlite3_open(([databasePath UTF8String], &database) == SQLITE_OK)
generates an error saying that there are too few arguments to sqlite3_open. How many arguments are required? How can this be fixed?
You've got your brackets in not quite the right place - so you're calling sqlite3_open( ) with just one argument, the result of the 'is-equal' test.
This is probably closer:
if ( sqlite3_open( [databasePath UTF8String], &database ) == SQLITE_OK )
See also the docs for sqlite3_open( ) - there are three alternative signatures, accepting 2 or 4 args:
int sqlite3_open(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);
int sqlite3_open16(
const void *filename, /* Database filename (UTF-16) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);
int sqlite3_open_v2(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb, /* OUT: SQLite db handle */
int flags, /* Flags */
const char *zVfs /* Name of VFS module to use */
);