C
C#3y ago
Ash_

How do i create a external file containing previously entered strings?

My program (a gtin verifier) asks the user to enter a gtin, which it saves as a string. After that the Method returns a true or false, depending on if the code is valid or not. for efficiency's sake i want it to save every input of the user and the true/false result to a file so if someone enters a code that was already calculated it just reads the result from the file instead of having to acutally calculate it, i'll send the code in a bit
31 Replies
Ash_
Ash_OP3y ago
the language for the user is german but that should not matter:
using System;
namespace Prüfzahlrechner
{
internal static class Program
{
public static void Main()
{
bool nochmal;
do
{
Console.Clear();
Console.Write("Bitte geben Sie den Code ein: ");
string gtin = Console.ReadLine();
Console.WriteLine(Gtin.Calculate(gtin) ? "Der Code ist funktionsfähig" : "Der Code ist nicht funktionsfähig");
Console.WriteLine("Nächster Code? (Y/n)");
string temp = Console.ReadLine();
nochmal = temp != "n";
} while (nochmal);
}
}
}
using System;
namespace Prüfzahlrechner
{
internal static class Program
{
public static void Main()
{
bool nochmal;
do
{
Console.Clear();
Console.Write("Bitte geben Sie den Code ein: ");
string gtin = Console.ReadLine();
Console.WriteLine(Gtin.Calculate(gtin) ? "Der Code ist funktionsfähig" : "Der Code ist nicht funktionsfähig");
Console.WriteLine("Nächster Code? (Y/n)");
string temp = Console.ReadLine();
nochmal = temp != "n";
} while (nochmal);
}
}
}
ero
ero3y ago
Why not save it into a list, or some other collection? Does it need to be in a file on the disk?
Ash_
Ash_OP3y ago
don't really care what it's called nor where it is, it just needs to be persistent across restarts of the program
ero
ero3y ago
You should care. This it's your program If you don't care, why should we? If it needs to persist through restarts, then yes, a file is what you want There are databases which can do this for you, but plain text files work fine too
Ash_
Ash_OP3y ago
i do care a bit, tho as long as the result is the same i don't really care with wich method someone recommends me to save it with, as long as it means i don't need to re-write my program
ero
ero3y ago
Look into File.AppendText and File.ReadLines
Ash_
Ash_OP3y ago
a whole database seems overkill, i'd imagine something like that:
<code> <something to show the code ends here> <result>
12345678,1
12345678 1
<code> <something to show the code ends here> <result>
12345678,1
12345678 1
or anything like that
MODiX
MODiX3y ago
Method: System.IO.File.AppendText(String) Creates a StreamWriter that appends UTF-8 encoded text to an existing file, or to a new file if the specified file does not exist.
React with ❌ to remove this embed.
MODiX
MODiX3y ago
Method: System.IO.File.ReadLines(String) Reads the lines of a file. Method: System.IO.File.ReadLines(String, Encoding) Read the lines of a file that has a specified encoding. Method: System.IO.File.ReadLinesAsync(String, CancellationToken) Asynchronously reads the lines of a file. 3/4 results shown ~ Click Here for more results
React with ❌ to remove this embed.
ero
ero3y ago
You could for example store all your info for your entry in one line Then you'd File.ReadLines(...).Select(...), and in the Select, Split() the line on some delimiter
Ash_
Ash_OP3y ago
i'm not really following, i'll try something
ero
ero3y ago
Then parse each split value and deserialize that into some real collection or object Another idea is using an actual file format like xml or json Using those you can use the JsonSerializer and XmlSerializer classes
Ash_
Ash_OP3y ago
that just confused me more... i'd imagine something like this:
public static string Db(string gtin)
{
if (gtin == "<somewhere in the file>") ;
{
return gtin;
}
else
{
/*
* create file
* add gtin to file
* add seperator to file
* add Gtin.Calculate(gtin) to file
* add seperator to file
*/
}
}
public static string Db(string gtin)
{
if (gtin == "<somewhere in the file>") ;
{
return gtin;
}
else
{
/*
* create file
* add gtin to file
* add seperator to file
* add Gtin.Calculate(gtin) to file
* add seperator to file
*/
}
}
ero
ero3y ago
What does the file store again? The calculated value? And what type does Gtin.Calculate return?
Ash_
Ash_OP3y ago
A bool
ero
ero3y ago
Hm, you're storing a bool to the file?
Ash_
Ash_OP3y ago
The the gtin-code itself and the result
ero
ero3y ago
Hm. Then would it make more sense only to store the code? And to only store the code of those which are valid codes?
Ash_
Ash_OP3y ago
Not really, I'd like it to store whatever the user enters
ero
ero3y ago
Hm, right Do you have an example input?
Ash_
Ash_OP3y ago
12345678,1. For example, the"," is the seperator from string to bool and the dot is the end of that entry, just chose them at the moment
ero
ero3y ago
I meant more the user input
Ash_
Ash_OP3y ago
Oh The input is simply a 8, 13 or 14 digit number as a string The method for the calculation returns the bool And I'll be gone for about half an hour, do you still need any info?
ero
ero3y ago
That's fine
Dictionary<int, bool> _storedGtins;
string _filePath;

bool TryParseFile(out Dictionary<int, bool> values)
{
values = new();

foreach (var line in File.ReadLines(_filePath))
{
var split = line.Split(';');

if (split.Length != 2)
{
values = null;
return false;
}

var storedGtinStr = split[0];
var storedValueStr = split[1];

if (!int.TryParse(storedGtinStr, out var storedGtin))
{
value = null;
return false;
}

if (!bool.TryParse(storedValueStr, out var storedValue))
{
value = null;
return false;
}

value[storedGtin] = storedValue;
}

return true;
}

bool TryCalculateGtin(string gtinStr)
{
if (!int.TryParse(gtinStr, out var gtin))
{
return false;
}

if (_storedGtins.TryGetValue(gtin, out var valid))
{
return valid;
}

valid = Gtin.Calculate(gtin);

var output = $"{gtin};{valid}" + Environment.NewLine;

_storedGtins[gtin] = valid;
File.AppendText(_filePath, output);

return valid;
}
Dictionary<int, bool> _storedGtins;
string _filePath;

bool TryParseFile(out Dictionary<int, bool> values)
{
values = new();

foreach (var line in File.ReadLines(_filePath))
{
var split = line.Split(';');

if (split.Length != 2)
{
values = null;
return false;
}

var storedGtinStr = split[0];
var storedValueStr = split[1];

if (!int.TryParse(storedGtinStr, out var storedGtin))
{
value = null;
return false;
}

if (!bool.TryParse(storedValueStr, out var storedValue))
{
value = null;
return false;
}

value[storedGtin] = storedValue;
}

return true;
}

bool TryCalculateGtin(string gtinStr)
{
if (!int.TryParse(gtinStr, out var gtin))
{
return false;
}

if (_storedGtins.TryGetValue(gtin, out var valid))
{
return valid;
}

valid = Gtin.Calculate(gtin);

var output = $"{gtin};{valid}" + Environment.NewLine;

_storedGtins[gtin] = valid;
File.AppendText(_filePath, output);

return valid;
}
Or something And then call TryCalculateGtin() on your ReadLine, and then do something when that returns false if you want (tell the user the code isn't valid or what have you)
_filePath = "";

if (!TryParseFile(out _storedGtins))
{
throw new FormatException();
}

while (true)
{
var input = Console.ReadLine();

if (!TryCalculateGtin(input))
{
// or whatever
throw new ArgumentException();
}
}
_filePath = "";

if (!TryParseFile(out _storedGtins))
{
throw new FormatException();
}

while (true)
{
var input = Console.ReadLine();

if (!TryCalculateGtin(input))
{
// or whatever
throw new ArgumentException();
}
}
Ash_
Ash_OP3y ago
that was a little bit more than half an hour, but i'm back does not really work, can i call you and stream my display?
ero
ero3y ago
god no lmao i wrote this completely on my phone
Ash_
Ash_OP3y ago
oh... why
ero
ero3y ago
so i'm not surprised that it doesn't work because i'm not home
Ash_
Ash_OP3y ago
oh discord shows me a online desktop client for your profile... nvm then, maybe later
ero
ero3y ago
i'm at work now lol at the time i was on my phone
Ash_
Ash_OP3y ago
it's okay, it does not need to be done now or tomorrow, it's just for efficiencies sake so it works without that, just not as efficient
Want results from more Discord servers?
Add your server