Document function Transfer to calculate the row of text file - c++11

I want to transfer a function to calculate the row of a text file.
The compile can pass but the function can not be transferred. I want to know what happens.
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
int getLine( const char *filename)
{
ifstream infile(filename,ios::in);
if(!infile){
cout<<"can not open"<<filename<<'\n';
return 0;
}
int count=0;
infile.unsetf(ios::skipws);
char buff[300];
while(infile.getline(buff,300))
count++;
cout<<"the total line:"<<count<<endl;
infile.close();
return 0;
}
int getLineNoEmpty(const char* filename)
{
ifstream infile(filename,ios::in);
if(!infile){
cout<<"can not open"<<filename<<'\n';
return 0;
}
int count=0;
char buff[300];
while(infile.getline(buff,300))
{
if(sizeof(buff)==0)
continue;
else
count++;
}
cout<<"the total line without null string:"<<count<<endl;
return 0;
}
int main()
{
char filename[256];
cout<<"input filename:";
cin>>filename;
int getLine(const char &filename);
int getLineNoEmpty(const char &filename);
return 0;
}
The compile can pass but the function can not be transferred. I want to know what happens about it. It can output the result I want. And I don't know how to
realize the goal of calculating the total line without null string.

Firstly, You are just declaring 2 functions in main() without using them. Change
int main()
{
char filename[256];
cout<<"input filename:";
cin>>filename;
int getLine(const char &filename);
int getLineNoEmpty(const char &filename);
return 0;
}
to
int main()
{
char filename[256];
cout<<"input filename:";
cin>>filename;
getLine(filename);
getLineNoEmpty(filename);
return 0;
}

Related

Why is this code breaking on string input?

#include <iostream>
using namespace std;
string flip();
int x;
int main()
{
for(int i=0;i<10;++i){
cout<<"Press 1 and enter"<<endl;
cin>>x;
if(isalpha(x)==true){
cout<<"int pls"<<endl;
}
else if(x==1){
flip();
cout<<"flipped"<<endl;
}
else if(x!=1){
cout<<"try again"<<endl;
}
}
system("pause>0");
return 0;
}
string flip(){
string ans;
int y=rand()%2;
if(y==0){
string ans = "Heads";
cout<<ans<<endl;
}
else{
string ans = "Tails";
cout<<ans<<endl;
}
return ans;
}
whenever I put 2 instead of 1 it works and says try again but when i write some string like "fa"
the code closes instead of writing try again
if I change x to int and then if I try to input some string it just prints press 1 and enter 10 times instead of asking for an input again
The type of variable 'x'(=The argument of isalpha()) has to be char. If the type of 'x' is integer, the function(=isalpha()) recognizes 'x' as an ASCII value. How about trying this code?
char x;
int main()
{
for(int i=0;i<10;++i){
cout<<"Press 1 and enter"<<endl;
cin>>x;
if((bool)isalpha(x)==true){
cout<<"int pls"<<endl;
}
else if(x=='1'){
flip();
cout<<"flipped"<<endl;
}
else {
cout<<"try again"<<endl;
}
}
system("pause>0");
return 0;
}

C++11 std::threads not exiting

Could you please check the following code which is not exiting even after condition becomes false?
I'm trying to print numbers from 1 to 10 by first thread, 2 to 20 by second thread likewise & I have 10 threads, whenever count reaches to 100, my program should terminate safely by terminating all threads. But that is not happening, after printing, it stuck up and I don't understand why?
Is there any data race? Please guide.
#include<iostream>
#include<vector>
#include<thread>
#include<mutex>
#include<condition_variable>
std::mutex mu;
int count=1;
bool isDone = true;
std::condition_variable cv;
void Print10(int tid)
{
std::unique_lock<std::mutex> lock(mu);
while(isDone){
cv.wait(lock,[tid](){ return ((count/10)==tid);});
for(int i=0;i<10;i++)
std::cout<<"tid="<<tid<<" count="<<count++<<"\n";
isDone = count<100;//!(count == (((tid+1)*10)+1));
std::cout<<"tid="<<tid<<" isDone="<<isDone<<"\n";
cv.notify_all();
}
}
int main()
{
std::vector<std::thread> vec;
for(int i=0;i<10;i++)
{
vec.push_back(std::thread(Print10,i));
}
for(auto &th : vec)
{
if(th.joinable())
th.join();
}
}
I believe the following code should work for you
#include<iostream>
#include<vector>
#include<thread>
#include<mutex>
#include<condition_variable>
using namespace std;
mutex mu;
int count=1;
bool isDone = true;
condition_variable cv;
void Print10(int tid)
{
unique_lock<std::mutex> lock(mu);
// Wait until condition --> Wait till count/10 = tid
while(count/10 != tid)
cv.wait(lock);
// Core logic
for(int i=0;i<10;i++)
cout<<"tid="<<tid<<" count="<<count++<<"\n";
// Release the current thread thus ensuring serailization
cv.notify_one();
}
int main()
{
std::vector<std::thread> vec;
for(int i=0;i<10;i++)
{
vec.push_back(std::thread(Print10,i));
}
for(auto &th : vec)
{
if(th.joinable())
th.join();
}
return 0;
}

read routine of the linux kernel module gets called infinite times [duplicate]

I am working on simple character device driver. I have implemented read and write functions in the module, the problem is when I try to read the device file using cat /dev/devicefile it is going into infinite loop i.e. reading the same data repeatedly. Can someone suggest me any solution to this problem? Below is my driver code.
#include<linux/module.h>
#include<linux/fs.h>
#include<linux/string.h>
#include<asm/uaccess.h>
#include<linux/init.h>
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("character device driver");
MODULE_AUTHOR("Srinivas");
static char msg[100]={0};
static int t;
static int dev_open(struct inode *, struct file *);
static int dev_rls(struct inode *, struct file *);
static ssize_t dev_read(struct file *, char *,size_t, loff_t *);
static ssize_t dev_write(struct file *, const char *, size_t,loff_t *);
static struct file_operations fops =
{
.read = dev_read,
.open = dev_open,
.write = dev_write,
.release = dev_rls,
};
static int himodule( void )
{
t = 0;
t = register_chrdev(0, "chardevdriver", &fops);
if (t < 0)
printk(KERN_ALERT"device registration failed\n");
else
printk(KERN_ALERT"device registered successfully\n");
printk(KERN_ALERT"major number is %d", t);
return 0;
}
static void byemodule(void)
{
unregister_chrdev(t, "chardevdriver");
printk(KERN_ALERT"successfully unregistered\n");
}
static int dev_open(struct inode *inod, struct file *fil)
{
printk(KERN_ALERT"inside the dev open");
return 0;
}
static ssize_t dev_read(struct file *filp, char *buff, size_t len, loff_t *off)
{
short count = 0;
while (msg[count] != 0) {
put_user(msg[count], buff++);
count++;
}
return count;
}
static ssize_t dev_write(struct file *filp, const char *buff, size_t len, loff_t *off)
{
short count = 0;
printk(KERN_ALERT"inside write\n");
memset(msg,0,100);
printk(KERN_ALERT" size of len is %zd",len);
while (len > 0) {
msg[count] = buff[count];
len--;
count++;
}
return count;
}
static int dev_rls(struct inode *inod,struct file *fil)
{
printk(KERN_ALERT"device closed\n");
return 0;
}
module_init(himodule);
module_exit(byemodule);
.read function should also correctly process its len and off arguments. The simplest way to implement reading from memory-buffered file is to use simple_read_from_buffer helper:
static ssize_t dev_read(struct file *filp, char *buff, size_t len, loff_t *off)
{
return simple_read_from_buffer(buff, len, off, msg, 100);
}
You can inspect code of that helper (defined in fs/libfs.c) for educational purposes.
BTW, for your .write method you could use simple_write_to_buffer helper.
You are not respecting the buffer size passed into the dev_read function, so you may be invoking undefined behaviour in cat. Try this:
static ssize_t dev_read( struct file *filp, char *buff, size_t len, loff_t *off )
{
size_t count = 0;
printk( KERN_ALERT"inside read %d\n", *off );
while( msg[count] != 0 && count < len )
{
put_user( msg[count], buff++ );
count++;
}
return count;
}
This problem can be solved by correctly setting *off (fourth parameter of my_read()).
You need to return count for the first time and zero from second time onwards.
if(*off == 0) {
while (msg[count] != 0) {
put_user(msg[count], buff++);
count++;
(*off)++;
}
return count;
}
else
return 0;

Compare source files on function level

I would like to compare two source files. While the output will return the functions that were changed. And not the lines.
My question is, what is the best why to find the start of a function and the end of it. If you know the row number.
Source files are in c.
Example
File Old
#include <stdio.h>
void checkPrimeNumber();
int main()
{
checkPrimeNumber(); // no argument is passed to prime()
return 0;
}
void checkPrimeNumber()
{
int flag=0;
printf("Enter a positive integer: ");
}
file New
#include <stdio.h>
void checkPrimeNumber();
int main()
{
checkPrimeNumber(); // no argument is passed to prime()
return 0;
}
void checkPrimeNumber()
{
int flag=1;
printf("Enter a positive integer: ");
}
Change is in fileNew flag=1;
Result will be
void checkPrimeNumber()
{
int flag=1;
printf("Enter a positive integer: ");
}

Convert "Tcl_Obj* const objv[]" to "char** argv"

I'm using Tcl 8.6 and I'm trying to do something like this to add functions to the tcl interpreter
Tcl_Interp* interp,
void init() {
interp = Tcl_CreateInterp();
}
void add_tcl_function(char* cmd, function<int(int,char**)> F) {
obj2argv* o2a = new obj2argv;
auto lambda_proc = [&](
ClientData cdata,
Tcl_Interp* interp,
int objc,
Tcl_Obj* const objv[])
{
o2a->set(objc, objv);
F(objc, o2a->get_argv());
};
auto lamba_delete = [&](
delete o2a;
};
Tcl_CreateObjCommand(interp, cmd, lamda_proc, NULL, lamda_delete);
}
What I'm wondering is how to convert "Tcl_Obj* const objv[]" to "char** argv"?
I was thinking about creating a class:
class obj2argv {
obj2argv();
void set(int objc, Tcl_Obj* const objv[]);
char** get_argv();
private:
//...
};
any ideas on how to implement set() and get_argv()?
Is there an easier way to do this?
Thanks.
obj2argv* o2a = new obj2argv;
If you're interfacing a function that's fundamentally working with const char** for arguments, you should register the function with Tcl_CreateCommand and let Tcl handle the mapping to strings for you. It already has all the mechanisms required.
More formally, you are dealing with a gluing function with this signature:
typedef int (Tcl_CmdProc) (ClientData clientData, Tcl_Interp *interp,
int argc, CONST84 char *argv[]);
The CONST84 should be read as being plain const in all new code, and ClientData is a pointer-sized value that Tcl just hands around and never inspects (same as with your existing code).
If you are going to do the mapping yourself, Tcl_GetString takes a Tcl_Obj* and returns the char* representation of it. The representation should be usually treated as const; it simply isn't formally typed as such for historical reasons.
I wanted to add some more information:
I gave up on using lambda's because when I added capture list it won't convert the lambda to a function pointer for some reason. So I went with the traditional approach (see below). EXCEPT: I still have not idea why the TCL document says
typedef int Tcl_CmdProc(
ClientData clientData,
Tcl_Interp *interp,
int argc,
const char *argv[]);
But the compiler requires this to compile:
typedef int Tcl_CmdProc(
ClientData clientData,
Tcl_Interp *interp,
int argc,
Tcl_Obj* const* argv);
The Code:
int cmd_dispatch(
ClientData clientData,
Tcl_Interp* interp,
int argc,
Tcl_Obj* const* argv)
{
function<int(int,char**)> F = *(function<int(int,char**)>*)clientData;
return F(argc, (char**) argv); // <= CAST DOESN'T SEEM RIGHT
}
void cmd_delete(ClientData clientData)
{
}
void add_tcl_function(const char* cmd, function<int(int,char**)> F) {
Tcl_CreateObjCommand(interp, cmd, cmd_dispatch, (void*)&F, cmd_delete);
}
VERSION 2:
struct cmd_data {
//Tcl_Interp* interp,
function<int(int,char**)> F;
int argc;
char* argv[MAX_ARGS];
};
int cmd_dispatch(
ClientData clientData,
Tcl_Interp* interp,
int argc,
Tcl_Obj* const* objv)
{
auto cmd_data1 = (struct cmd_data*) clientData;
cmd_data1->argc = argc;
for(int i=0; ((i < argc) && (i < MAX_ARGS)); i++) {
cmd_data1->argv[i] = Tcl_GetString(objv[i]);
// Who owns object returned by Tcl_GetString?
// memory leak? or invalid after return from function?
// garbage collected by tcl interp?
}
return cmd_data1->F(argc, cmd_data1->argv);
}
void cmd_delete(ClientData clientData)
{
auto cmd_data1 = (struct cmd_data*) clientData;
if (cmd_data1) {
delete cmd_data1;
}
}
void add_tcl_function(const char* cmd, function<int(int,char**)> F) {
auto cmd_data1 = new struct cmd_data;
cmd_data1->F = F;
Tcl_CreateObjCommand(interp, cmd, cmd_dispatch, (void*)cmd_data1, cmd_delete);
}
void init_tcl_commands() {
auto lambda_hello = [&](int argc ,char** argv) -> int {
cout << "HELLO WORLD!\n";
return 0;
};
tcl_backend::add_tcl_function("hello", lambda_hello);
}

Resources