How do I need to change the datatype in a textfile in order to read a String and not a Integer (C++/CLI, OleDb)? - c++-cli

My goal is it to read from a text file. This text file contains different columns and rows for each value. I can read the file as long as I don't change the datatype that windows set on its own. But I do not want the "plz" and "nr" column to be numbers (integers) but a text (String) value because a plz could contain values like "01979" and the nr could contain something like "4a". As a number the starting zero would be lost and this way something like a postcard would never reach its intended destination.
This way I need to change the datatype in a "schema.ini" file. But it doesn't work. I think I make some mistakes and do not follow the tutorial the way I need to do: "Schema.ini File"
Everytime I tried to read a String I got an Exception because it still want to read an Int32-values that I would need to convert into a string.
I did name the file "kunde.txt"
knr|nachname|vorname|plz|ort|strasse|nr
1|Müller|Johan|12345|Muster|Musterstr|1
2|Kummer|Freude|23456|Feeling|Gefühlswelt|4a
Col 0 = knr, 1 = nachname, 2 = vorname, 3 = plz, 4 = ort, 5 = strasse, 6 = nr
con->ConnectionString =
"Provider=Microsoft.JET.OLEDB.4.0;" +
"Data Source=D:/C++/Quellen;" +
"Extended Properties=text";
// ....
meineKunden->CommandText =
"SELECT knr, nachname, vorname, plz, ort, strasse, nr " +
"FROM kunde.txt ";
// ....
String ^ str;
while(reader->Read()){
str += Convert::ToString(reader->GetInt32(0));
str += " ";
str += reader->GetString(3);
str += " ";
str += reader->GetString(6);
str += "\r\n";
}
this->txb_Insert->Text = str;
My schema.ini
[kunde.txt]
ColNameHeader=True
Format=Delimited(|)
3=plz Char Width 5
6=nr Char Width 10
I did try with "Col3" instead of "3". I did use "Text" rather tan "Char", and I did even attempted it without Width. But everytime I got the same failure message. Even if i use 4 or 7 ... since I am not sure how it will be counted in the ini / txt file.
Exception:
System.InvalidCastException: Die angegebene Umwandlung ist ungültig.
bei System.Data.OleDb.ColumnBinding.ValueString()
bei System.Data.OleDb.OleDbDataReader.GetString(Int32 ordinal)
The exception is calls already by str += reader->GetString(3)
If I am correct column 3 contains plz, this way.
Could someone please say what I do understand wrong with the schema.ini file?
Since I could read the file without mistakes as long as I doesn't try to specific change the datatype in some columns the problems need to be with the ini file. At least I think so.
EDIT: I did change my ini-file to:
[kunde.txt]
ColNameHeader=True
Format=Delimited(|)
Col1="knr" Integer
Col2="nachname" Text
Col3="vorname" Text
Col4="plz" Text
Col5="ort" Text
Col6="strasse" Text
Col7="nr" Text
Now it works for "plz" but the exception is called in the last row, when I call the "nr". WTF?

You have to maintain that the way you read data from the file suits the way it's written in .
So if the file in not written by you and you have to use it,try to know if it has a specific structure (for ex: fixed length record delimited fields , fixed length record fixed length fields.. etc) and use a way that suits this structure to read it.
Also try to know how fields of records are written in details because the way you read is the same as you write .

Related

How to count the words of a string without using any function in abap

Hello Experts
I need a help to count the words of string without using any function in ABAP.
We can only use do loop and if condition.
Please Help
METHODS count_words
IMPORTING
iv_text TYPE string
RETURNING
VALUE(rv_result) TYPE i.
METHOD count_words.
CONSTANTS lc_space TYPE string VALUE ` `.
DATA(lv_remaining_text) = iv_text.
DATA(lv_last_char) = ``.
DO.
IF lv_remaining_text IS INITIAL.
RETURN. " or EXIT if you omit the METHOD around this
ENDIF.
DATA(lv_next_char) = lv_remaining_text(1).
IF lv_next_char <> lc_space AND
( lv_last_char IS INITIAL OR
lv_last_char = lc_space ).
rv_result = rv_result + 1.
ENDIF.
lv_last_char = lv_next_char.
lv_remaining_text = lv_remaining_text+1.
ENDDO.
ENDMETHOD.
Please don't code like this in practice. This sort of low-level character juggling is only for educational purposes.
In real life, please use something like this:
METHOD count_words_cleanly.
rv_result = count( val = iv_text
regex = `(\s\S|^\S)` ).
ENDMETHOD.
You could count the number of spaces between your words.
You need at least STRLEN to determine the string length... without it I dont think this works. CONDENSE might be useful in some cases... give it a try without CONDENSE.
DATA a TYPE string VALUE 'MY NAME IS JOHN'.
DATA c TYPE i.
DATA d TYPE c.
DATA words TYPE i value 1.
DATA e TYPE i VALUE 0.
CONDENSE a.
c = STRLEN( a ).
DO c TIMES.
d = a+e(1).
e = e + 1.
IF d = ' '.
words = words + 1.
ENDIF.
ENDDO.
WRITE words. // just as output ... delete on demand

Converting binary to base 4

What I hope to achieve:
I want to convert text to DNA (which is a base 4 system, "a,G,T,c")
How I plan to do it:
Convert text string to binary,
Dim BinaryConvert As String = ""
For Each C As Char In Textbox1.Text
Dim s As String = System.Convert.ToString(AscW(C), 2).PadLeft(8, "0")
BinaryConvert &= s
Next
Textbox1.Text = BinaryConvert '//Changes the textbox1.Text into binary form
Then convert binary to base 4 via Pseudocode solution:
if (length of binary String is an odd number) add a zero to the front (leftmost position) of the String.
Create an empty String to add translated digits to.
While the original String of binary is not empty {
Translate the first two digits only of the binary String into a base-4 digit, and add this digit to the end (rightmost) index of the new String.
After this, remove the same two digits from the binary string and repeat if it is not empty.
}
The idea behind converting binary to DNA is simply setting G and T equal to one, with c and a equal to zero (G=T=1, a=c=0).
So all I have to do is convert the string to binary first, and then into base 4, in order to convert text to genetic code. Could you please help me write the code to convert binary to base 4.
Thank you for the help!
Converting to base 4 from base 2 is pretty simple. Since 4 itself is the 2nd power of 2, this means you can simply combine two bits to create one base 4 place (2 bits can represent 4 possible values, while 1 base 4 place can also represent 4 possible values). For example:
11100100 (base 2) = 3210 (base 4)

Reading sparse columns from a CSV

I get a CSV that I need to read into a SQL table. Right now it's manually uploaded with a web application, but I want to move this into SQL server. Rather than port my import script straight across into a script in SSIS, I wanted to check and see if there was a better way to do it.
The issue with this particular CSV is that the first few columns are known, and have appropriate headers. However, after that group, the rest of the columns are sparsely populated and might not even have headers.
Example:
Col1,Col2,Col3,,,,,,
value1,value2,value3,,value4
value1,value2,value3,value4,value5
value1,value2,value3,,value4,value5
value1,value2,value3,,,value4
What makes this tolerable is that everything after Col3 can get concatenated together. The script checks each row for these trailing columns and puts them together into a "misc" column. It has to do this in a bit of a blind method because there is no way of knowing ahead of time how many of these columns will be out there.
Is there a way to do this with SSIS tools, or should I just port my existing import script to an SSIS script task?
Another option outside of SSIS is using BulkInsert with format files.
Format files allow you to describe the format of the incoming data.
For example..
9.0
4
1 SQLCHAR 0 100 "," 1 Header1 SQL_Latin1_General_CP1_CI_AS
2 SQLCHAR 0 100 "," 2 Header2 SQL_Latin1_General_CP1_CI_AS
3 SQLCHAR 0 100 "," 3 Header3 SQL_Latin1_General_CP1_CI_AS
4 SQLCHAR 0 100 "\r\n" 4 Misc SQL_Latin1_General_CP1_CI_AS
Bulk Insert>> http://msdn.microsoft.com/en-us/library/ms188365.aspx
Format Files >> http://msdn.microsoft.com/en-us/library/ms178129.aspx
Step 0. My test file with an additional line
Col1,Col2,Col3,,,,,,
value1,value2,value3,,value4
value1,value2,value3,value4,value5
value1,value2,value3,,value4,value5
value1,value2,value3,,,value4
ends,with,comma,,,value4,
Drag a DFT on the Control flow surface
Inside the DFT, on the data flow surface, drag a Flat file source
Let is map by itself to start with. Check Column names in the first data row.
You will see Col1, Col2, Col3 which are your known fields.
You will also see Column 3 through Column 8. These are the columns
that need to be lumped into one Misc column.
Go to the Advanced section of the Flat File Manager Editor.
Rename Column 3 to Misc. Set field size to 4000.
Note: For longer than that, you would need to use Text data type.
That will pose some challenge, so be ready for fun ;-)
Delete Columns 4 through 8.
Now add a script component.
Input Columns - select only Misc field. Usage Type: ReadWrite
Code:
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
string sMisc = Row.Misc;
string sManipulated = string.Empty;
string temp = string.Empty;
string[] values = sMisc.Split(',');
foreach (string value in values)
{
temp = value;
if (temp.Trim().Equals(string.Empty))
{
temp = "NA";
}
sManipulated = string.Format("{0},{1}", sManipulated, temp);
}
Row.Misc = sManipulated.Substring(1);
}
-- Destination.
Nothing different from usual.
Hope I have understood your problem and the solution works for you.

Vi: how to automatically insert spaces

I'm trying to write a nice feature for crazy people like me who like there lines to be perfectly aligned.
I often write some file in which the format is "key = value".
Since the key may contain an indeterminate number of character, one have to manually align the "=" symbols which is not cool.
Is there a way to tell vi "when someone type the equal character, then insert as spaces as necessary to go to the column 25, then write an the equal symbol"?
The second step will be to define a shortcut to apply this format to an entire file.
Any help would be appreciated.
Ben.
Map the behavior of = in Insert Mode.
Next code will add spaces until column 24 from current cursor position and will add an equal sign after it. If there were characters after cursor position (suppose in a middle of a word), those characters will be moved after column 25. Add it to your vimrc file and try.
"" If length of the line is more or equal to 24, add an equal sign at the end.
"" Otherwise insert spaces from current position of cursor until column 24
"" and an equal sign, moving characters after it.
function My_align()
let line_len = strlen( getline('.') )
if line_len >= 24
s/$/=/
return
endif
let col_pos = col('.')
exe 's/\%#\(.\|$\)/\=submatch(1) . printf( "%' . (24 - col_pos) . 's%s", " ", "=" )/'
endfunction
inoremap = <Esc>:call My_align()<CR>A
For second step, use the multiple repeats command, check for an equal sign and insert spaces until column 25 just before it. Won't work if equal sign is after column 25 before executing it, but you get the idea.
:g/=/exe 's/=/\=printf( "%' . ( 24 - stridx( getline('.'), "=" ) ) . 's", " " ) . submatch(0)/'

How to load 2D array from a text(csv) file into Octave?

Consider the following text(csv) file:
1, Some text
2, More text
3, Text with comma, more text
How to load the data into a 2D array in Octave? The number can go into the first column, and all text to the right of the first comma (including other commas) goes into the second text column.
If necessary, I can replace the first comma with a different delimiter character.
AFAIK you cannot put stings of different size into an array. You need to create a so called cell array.
A possible way to read the data from your question stored in a file Test.txt into a cell array is
t1 = textread("Test.txt", "%s", "delimiter", "\n");
for i = 1:length(t1)
j = findstr(t1{i}, ",")(1);
T{i,1} = t1{i}(1:j - 1);
T{i,2} = strtrim(t1{i}(j + 1:end));
end
Now
T{3,1} gives you 3 and
T{3,2} gives you Text with comma, more text.
After many long hours of searching and debugging, here's how I got it to work on Octave 3.2.4. Using | as the delimiter (instead of comma).
The data file now looks like:
1|Some text
2|More text
3|Text with comma, more text
Here's how to call it: data = load_data('data/data_file.csv', NUMBER_OF_LINES);
Limitation: You need to know how many lines you want to get. If you want to get all, then you will need to write a function to count the number of lines in the file in order to initialize the cell_array. It's all very clunky and primitive. So much for "high level languages like Octave".
Note: After the unpleasant exercise of getting this to work, it seems that Octave is not very useful unless you enjoy wasting your time writing code to do the simplest things. Better choices seems to be R, Python, or C#/Java with a Machine Learning or Matrix library.
function all_messages = load_data(filename, NUMBER_OF_LINES)
fid = fopen(filename, "r");
all_messages = cell (NUMBER_OF_LINES, 2 );
counter = 1;
line = fgetl(fid);
while line != -1
separator_index = index(line, '|');
all_messages {counter, 1} = substr(line, 1, separator_index - 1); % Up to the separator
all_messages {counter, 2} = substr(line, separator_index + 1, length(line) - separator_index); % After the separator
counter++;
line = fgetl(fid);
endwhile
fprintf("Processed %i lines.\n", counter -1);
fclose(fid);
end