Here is my code that reads structs from a file.
int _tmain(int argc, _TCHAR* argv[])
{
typedef struct
{
char name_1[100];
char Max_1[100];
char Min_1[100];
} power_line_name;
int numLines;
StreamReader ^ sr1=File::OpenText("testcpp\\test\\powerline.txt");
while(sr1->ReadLine())
{
numLines++;
}
power_line_name* power_list=new power_line_name[numLines];
//power_line_name power_list[5];
StreamReader ^ sr=File::OpenText("testcpp\\test\\powerline.txt");
array<System::String ^> ^power_line;
array<System::String ^> ^d_line;
String ^ eachString;
String ^ eachString_2;
String ^ eachString_3;
int i=0;
char nstring[100];
try
{
String^ s="";
while (s=sr->ReadLine())
{
power_line=s->Split(':');
Console::WriteLine(s);
d_line=power_line[1]->Split('|');
for(int a=0;a<d_line->Length;a++)
{
pin_ptr<const wchar_t> wch = PtrToStringChars(d_line[a]);
size_t origsize = wcslen(wch) + 1;
size_t convertedChars = 0;
if(a==0)
{
wcstombs_s(&convertedChars, power_list[i].name_1, origsize, wch, _TRUNCATE);
strcat_s(power_list[i].name_1, " (char *)");
}
if(a==1)
{
wcstombs_s(&convertedChars, power_list[i].Max_1, origsize, wch, _TRUNCATE);
strcat_s(power_list[i].Max_1, " (char *)");
}
if(a==2)
{
wcstombs_s(&convertedChars, power_list[i].Min_1, origsize, wch, _TRUNCATE);
strcat_s(power_list[i].Min_1, " (char *)");
}
}
i++;
}
Console::WriteLine(s);
}
finally
{
if(sr)
delete (IDisposable^)(sr);
}
return 0;
}
Here is its output:
power_list[0].name_1=aaaa
power_list[0].Max_1=1111111
power_list[0].Min_1=222222
power_list[1].name_1=aaaa
power_list[1].Max_1=333333
power_list[1].Min_1=444444
power_list[2].name_1=aaaa
power_list[2].Max_1=333333
power_list[2].Min_1=444444
power_list[3].name_1=aaaa
power_list[3].Max_1=33333
power_list[3].Min_1=66666
If Max_1 and Min_1 are the same for some two elements, I would like the second element to be removed.
So the new ouput would be:
power_list[0].name_1=aaaa
power_list[0].Max_1=1111111
power_list[0].Min_1=222222
power_list[1].name_1=aaaa
power_list[1].Max_1=333333
power_list[1].Min_1=444444
power_list[2].name_1=aaaa
power_list[2].Max_1=33333
power_list[2].Min_1=66666
i don't know how to do??
I am not familiar with c++-cli syntax, so here is one way to do it, in pseudo-code:
for i from 0 to n-1
for j from i+1 to n-1
if list[i].Max_1 == list[j].Max_1 and list[i].Min_1 == list[j].Min_1
mark j as duplicate
for i from 0 to n-1
if i is not marked duplicate
output i
This seems to be the simplest way to do it.
Another more sophisticated way: sort your array; then all duplicate entries will be adjacent, which will make comparisons easier. Maybe someone else will describe this in another answer.
Related
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;
I have to mix C++ with dot net C++. I see this error. I have already Googled a lot. Tried many methods. Still not working. Any help appreciated.
int _tmain(int argc, _TCHAR* argv[])
{
typedef struct
{
char all_srting[200];
char name_1[100];
char Max_1[100];
char Min_1[100];
}power_line_name;
int numLines;
StreamReader ^ sr1=File::OpenText("powerline.txt");
while(sr1->ReadLine())
{
numLines++;
}
power_line_name* power_list=new power_line_name[numLines];
StreamReader ^ sr=File::OpenText("powerline.txt");
array<System::String ^> ^power_line;
array<System::String ^> ^power_line_nospace;
array<System::String ^> ^d_line;
array<System::String ^> ^all_powrline_string;
int i=0;
char nstring[100];
try
{
String^ s="";
while (s=sr->ReadLine())
{
power_line=s->Split(':');
power_line_nospace=power_line[1]->Split(' ');
d_line=power_line_nospace[1]->Split('|');
for(int a=0;a<d_line->Length;a++)
{
pin_ptr<const wchar_t> wch = PtrToStringChars(d_line[a]);
size_t origsize = wcslen(wch) + 1;
size_t convertedChars = 0;
if(a==0)
{
wcstombs_s(&convertedChars, power_list[i].name_1, origsize, wch, _TRUNCATE);
//strcat_s(power_list[i].name_1, " (char *)");
}
if(a==1)
{
wcstombs_s(&convertedChars, power_list[i].Max_1, origsize, wch, _TRUNCATE);
//strcat_s(power_list[i].Max_1, " (char *)");
}
if(a==2)
{
wcstombs_s(&convertedChars, power_list[i].Min_1, origsize, wch, _TRUNCATE);
//strcat_s(power_list[i].Min_1, " (char *)");
}
}
i++;
}
Console::WriteLine(s);
}
finally
{
if(sr)
delete (IDisposable^)(sr);
}
return 0;
}
I get this message: power_line=s->Split(':');<-----fatal error c1001:an internal error has occurred in the compiler
and
error fatal error lnk1000 internal error during image::bulidimage
what can i do?
I met the same error when use boost::iequals to compare two std::string like below:
std::for_each(bds.begin(),bds.end(),[&](std::string str){if(boost::iequals("must",str)) printf("matched\n");});
i compiled this code with vs 2010 and boost version 1.58.
To solved the error just replace the std::for_each() with for().so i guess the compile r and boosts lib conflicted.
probably there is a smart way to do that , but anyway i get error on this :
-(int*)decimalBinary:(int)decimal
{
int i=0;
int *bin;
while (decimal!=0)
{
bin[i]=decimal%2;
decimal=decimal/2;
i++;
}
return bin;
}
on the modulo line . why ?
And whats the better way to get it to array ?
Declaring
int *bin;
sets aside space for a pointer but doesn't make it point to an object. It is crucial to initialize bin before using it.
To solve your problem you can declare an array bin[4] in caller function (int main) and then pass *bin to your calling function.
The following code is adapted from This answer on how to print an integer in binary format. Storing "binary digits" into an int array is added into the code below:
#include <stdio.h> /* printf */
#include <stdlib.h> /* strtol */
const char *byte_to_binary(long x);
int main(void)
{
long lVal;
int i, len, array[18];
char buf[18];
{ /* binary string to int */
char *tmp;
char *b = "11010111001010110";
lVal=strtol(b, &tmp, 2); //convert string in "base 2" format to long int
printf("%d\n", lVal);
}
{
printf("%s", byte_to_binary(lVal));
/* byte to binary string */
sprintf(buf,"%s", byte_to_binary(lVal));
}
len = strlen(buf);
for(i=0;i<len;i++)
{ //store binary digits into an array.
array[i] = (buf[i]-'0');
}
getchar();
return 0;
}
const char *byte_to_binary(long x)
{
static char b[17]; //16 bits plus '\0'
b[0] = '\0';
char *p = b;
int z;
for (z = 65536; z > 0; z >>= 1) //2^16
{
*p++ = (x & z) ? '1' : '0';
}
return b;
}
const char *sentence = "He was not in the cab at the time.";
printf("\"%s\" has %d spaces\n", sentence, (int) ^ {
int i = 0;
int countSpaces = 0;
while (sentence[i] != '\0') {
if (sentence[i] == 0x20) {
countSpaces++;
}
i++;
}
return countSpaces;
});
This code simply counts the white space in a string, but for some reason it says 1606416608 spaces rather than 8. I'm not exactly sure what is going wrong, so thanks for any help!
You're passing the actual block to printf, not the result of the block. Instead, try
const char *sentence = "He was not in the cab at the time.";
printf("\"%s\" has %d spaces\n", sentence, (int) ^ {
int i = 0;
int countSpaces = 0;
while (sentence[i] != '\0') {
if (sentence[i] == 0x20) {
countSpaces++;
}
i++;
}
return countSpaces;
}()); // <-- note the extra parentheses here, indicating that you're calling the block
Ive tried to create my own implementation of a bignum library
I cant seem to get the factorial to work. If I ask it to solve 4!, it gives out 96. It multiplies 4 twice. similarly, 5! is 600, not 120. I haven't implemented division, so I cant/dont want to divide the answer by the number
//bignum project
#include <iostream>
using namespace std;
class bignum
{
public:
int number[100];
int dpos;
int operator/ (bignum);
bignum operator- (bignum);
bignum operator* (bignum);
bignum operator+ (bignum);
bignum operator= (string);
void output()
{
int begin=0;
for(int i=0; i<=99; i++)
{
if(number[i]!=0 || begin==1)
{
cout<<number[i];
begin=1;
}
}
}
};
bool num_is_zero(bignum k)
{
for(int a=0; a<=99; a++)
{
if(k.number[a]!=0)
{
return false;
}
}
return true;
}
bignum factorial(bignum a)
{
bignum j;
bignum fact;
fact="1";
while(!num_is_zero(a))
{
j="1";
fact=fact*a;
a=a-j;
}
return fact;
}
bignum bignum::operator= (string k)
{
int l;
l=k.length()-1;
for(int h=0; h<=99; h++)
{
number[h]=0;
}
for(int a=99; a>=0 && l>=0; a--)
{
number[a]=k[l]-'0';
l--;
}
}
bignum bignum::operator+ (bignum b)
{
bignum a;
int carry=0;
for(int k=0; k<=99; k++)
{
a.number[k]=0;
}
for(int i=99; i>=0; i--)
{
a.number[i]= number[i]+b.number[i]+a.number[i];
if(a.number[i]>9)
{
carry=(a.number[i]/10);
a.number[i-1]+=carry;
a.number[i]=(a.number[i]%10);
}
}
return (a);
}
bignum bignum::operator- (bignum c)
{
bignum a;
int sign=0;
for(int k=0; k<=99; k++)
{
a.number[k]=0;
}
for(int i=99; i>=0; i--)
{
if(number[i]<c.number[i])
{
number[i]+=10;
if(i!=0)
number[i-1]--;
}
a.number[i]=number[i]-c.number[i];
}
return (a);
}
bignum bignum::operator* (bignum b)
{
bignum ans;
int ans_grid[100][100],x,lines=0,carry,sum[100];
for(int a=0; a<=99; a++)
{
for(int b=0; b<=99; b++)
{
ans_grid[a][b]=0;
}
}
for(int i=99; i>=0; i--)
{
for(int j=i,x=99; j>=0; j--,x--)
{
ans_grid[lines][j]=(number[i]*b.number[x]);
}
lines++;
}
//------------------------------------------------Carry Forward and assign to ans------------------------------------------------//
for(int j=99; j>=0; j--)
{
for(int i=99; i>=0; i--)
{
if(ans_grid[j][i]>9 && i!=0)
{
carry=(ans_grid[j][i]/10);
ans_grid[j][i-1]+=carry;
ans_grid[j][i]%=10;
}
}
}
for(int col=99; col>=0; col--)
{
for(int row=99; row>=0; row--)
{
sum[col]+=ans_grid[row][col];
}
}
for(int i=99; i>=0; i--)
{
if(sum[i]>9 && i!=0)
{
carry=(sum[i]/10);
sum[i-1]+=carry;
sum[i]%=10;
}
}
for(int l=0; l<=99; l++)
ans.number[l]=sum[l];
//-------------------------------------------------------------------------------------------------------------------------------//
return (ans);
}
I think your problem is that sum is uninitialized in your operator*. I'm reluctant to give a partial answer, since I took the code and fiddled with it a bit, so here's my version which appears to work (and also prints "0" correctly):
Update: I couldn't resist making several structural improvements. I didn't touch your multiplication routine, so you should still be able to extract the bugfix even if you don't care for the rest.
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
class bignum
{
public:
int number[100];
bignum() { std::fill(number, number + 100, 0); }
bignum(const bignum & other) { std::copy(other.number, other.number + 100, number); }
bignum(const std::string &);
bignum & operator-=(const bignum &);
inline bignum operator-(const bignum & c) const { return bignum(*this) -= c; }
bignum operator*(const bignum &) const;
inline bignum & operator= (const std::string & k) { return *this = bignum(k); }
inline operator bool() const
{
for (size_t a = 0; a < 100; ++a)
if (number[a] != 0) return true;
return false;
}
};
std::ostream & operator<<(std::ostream & o, const bignum & b)
{
bool begun = false;
for (size_t i = 0; i < 100; ++i)
{
if (begun || b.number[i] != 0)
{
cout << b.number[i];
begun = true;
}
}
if (!begun) o << "0";
return o;
}
bignum::bignum(const std::string & k)
{
std::fill(number, number + 100, 0);
for(size_t h = 0; h < std::min(k.length(), 100U); ++h)
number[99 - h] = k[k.length() - 1 - h] - '0';
}
bignum & bignum::operator-=(const bignum & c)
{
for (int i = 99; i >= 0; --i)
{
if (number[i] < c.number[i])
{
number[i] += 10;
if (i != 0) --number[i-1];
}
number[i] -= c.number[i];
}
return *this;
}
bignum bignum::operator*(const bignum & b) const
{
bignum ans;
int ans_grid[100][100], lines = 0, carry, sum[100];
std::fill(sum, sum + 100, 0);
for (size_t i = 0; i < 100; ++i) std::fill(ans_grid[i], ans_grid[i] + 100, 0);
for(int i=99; i>=0; i--)
{
for(int j=i,x=99; j>=0; j--,x--)
{
ans_grid[lines][j]=(number[i]*b.number[x]);
}
lines++;
}
//------------------------------------------------Carry Forward and assign to ans------------------------------------------------//
for(int j=99; j>=0; j--)
{
for(int i=99; i>=0; i--)
{
if(ans_grid[j][i]>9 && i!=0)
{
carry=(ans_grid[j][i]/10);
ans_grid[j][i-1]+=carry;
ans_grid[j][i]%=10;
}
}
}
for(int col=99; col>=0; col--)
{
for(int row=99; row>=0; row--)
{
sum[col]+=ans_grid[row][col];
}
}
for(int i=99; i>=0; i--)
{
if(sum[i]>9 && i!=0)
{
carry=(sum[i]/10);
sum[i-1]+=carry;
sum[i]%=10;
}
}
for(int l=0; l<=99; l++)
ans.number[l]=sum[l];
//-------------------------------------------------------------------------------------------------------------------------------//
return (ans);
}
bignum factorial(bignum a)
{
bignum j; j = "1";
bignum fact; fact="1";
while(a)
{
fact = fact * a;
a = a-j;
}
return fact;
}
int main(int argc, char * argv[])
{
if (argc < 2) return 0;
bignum a;
a = std::string(argv[1]);
bignum b = factorial(a);
cout << a << std::endl << b << std::endl;
}
The string assignment is still broken for strings with more than one digit, but that wasn't your question I suppose...