Newbie here, currently studying C# course and totally new to coding and stuff.
Sorry if this question is already been asked, I've been googling for quite some time and still unable to find a proper answer or anything near it.
Question being simple. I have an array that contains string needs to be saved onto a file, needs to be retrieved when required.
example
string[] item_name = {"abc", "def", "ghi"};
float[] item_cost = {30f,20f,10f};
int[] item_qty = {10,20,30};
How do i go about saving all these data into a file (e.g .txt) and then retrieve at a button_click command?
try this.... u will get answer....
static void Main(string[] args)
{
while (true)
{
Console.WriteLine("Select your option: 1 for Write, 2 for Read, 3 for Search, others for exit");
int flag = Convert.ToInt32(Console.ReadLine());
if (flag != 1 && flag != 2 && flag != 3) break;
switch (flag)
{
case 1:
{
StreamWriter SW = new StreamWriter(#"C:\test.txt");
while (true)
{
Console.WriteLine("Enter some value for inset into text file, 0 for exit\n");
string temp = Console.ReadLine();
if (temp != "0")
{
SW.WriteLine(temp);
}
else
{
break;
}
}
//SW.Dispose();
SW.Close();
break;
}
case 2:
{
StreamReader SR = new StreamReader(#"C:\test.txt");
while (true)
{
Console.WriteLine(SR.ReadLine());
if (SR.EndOfStream == true)
break;
}
SR.Dispose();
SR.Close();
break;
}
case 3:
{
Console.Write("entre ur value:\t");
string value = Console.ReadLine();
StreamReader SR = new StreamReader(#"C:\test.txt");
bool flg = false;
while (true)
{
if (value == SR.ReadLine())
{
Console.WriteLine(value + " was found in ur text");
flg = true;
break;
}
if (SR.EndOfStream == true)
break;
}
if (flg != true)
{
Console.WriteLine("Sorry not found");
}
SR.Dispose();
SR.Close();
break;
}
default:
{
break;
}
}
}
}
Related
I hope I can explain my scenario the best I can.
I have code that when the "Load" button is clicked, all file names (if any) located in a predefined network directory path, are loaded to a text-area.
Currently there can be .txt, .xml files.
Contents could look like:
first_file_found.xml
second_file_found.xml
third_file_found.txt
Also, in the code there is another function "isCoValid" that performs an additional validation of the contents of these files, based on return value (true/false) of this function, the "Process" button is enabled:
if (IsFlatFile(fileName) || IsXMLFile(fileName))
{
if (isCoValid(fileName))
{
btnProcess.Enabled = true;
}
else
{
btnProcess.Enabled = false;
break;
}
}
Now I have to add a .csv file type, but this file does not required to perform the isCoValid function.
The text-area contents now look like:
first_file_found.xml
second_file_found.xml
third_file_found.txt
fourht_file_found.csv
My request for help is to ask how can the check to find out if there is a CSV file can be done, and also controlling the enabling of the "Process" button, but still respect the existing check for .txt, and .xml and the validation of contents?
I might have xml and text files, that aren't valid, but I still need to be able to process the .csv. file.
I did change it like this:
if (IsFlatFile(fileName) || IsXMLFile(fileName))
{
if (isCoValid(fileName))
{
btnProcess.Enabled = true;
}
else
{
btnProcess.Enabled = false;
break;
}
}
if (IsCSVFile(fileName))
{
btnProcess.Enabled = true;
}
But I am sure this is not correct and I would like to ask for some help if possible.
I hope I explained my problem with some clarity and straightforwardness, if not, please let me know and I can try to provide more information.
Thank you,
Erasmo
Additional Code Requested
public bool IsFlatFile(string FileName)
bool ReturnValue = false;
if (FileName.ToUpper().Right(4) == ".TXT")
{
if ((FileName.Substring(0, 2).ToUpper() == "MN") ||
(FileName.Substring(0, 2).ToUpper() == "CH"))
{
ReturnValue = true;
}
}
return ReturnValue;
}
public bool IsXMLFile(string FileName)
bool ReturnValue = false;
if (FileName.ToUpper().Right(4) == ".XML")
{
if ((FileName.Substring(0, 2).ToUpper() == "TR") ||
(FileName.Substring(0, 2).ToUpper() == "SK"))
{
ReturnValue = true;
}
}
return ReturnValue;
}
protected bool isCoValid(string fName)
{
bool retCode = false;
Parameters parms;
var reader = new AppSettingsReader();
Application app = new Application();
Package package = null;
try
{
package = app.LoadPackage(packagePath + "ValidateContents.dtsx", null);
parms = package.Parameters;
parms["ID"].Value = "";
parms["ImportFileName"].Value = fName;
parms["UserID"].Value = userName;
DTSExecResult results = package.Execute();
if (results == Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure)
{
foreach (Microsoft.SqlServer.Dts.Runtime.DtsError local_DtsError in package.Errors)
{
retCode = false;
resultText = resultText + "DTSX Package Execution results: " + local_DtsError.Description.ToString() + Environment.NewLine;
}
}
else
{
resultText = resultText + "Successful Process Completion." + Environment.NewLine + Environment.NewLine;
string sqlStr = "SELECT TOP 1 * FROM Validation WHERE Type = 'VALCO' AND CAST(CreatedDate AS DATE) = CAST(GETDATE() AS DATE)";
DataTable dt = new DataTable();
dt = GetDataSet(sqlStr);
if (dt.Rows.Count > 0)
{
foreach (DataRow row in dt.Rows)
{
if (row["Status"].ToString() == "Valid")
{
retCode = true;
resultText = "Output: Valid" + Environment.NewLine + "Press the 'Process' button to proceed.";
}
else
{
retCode = false;
resultText = "Output: " + row["Status"].ToString() + Environment.NewLine + "Validation Fail: " + row["Error"].ToString();
}
}
}
else
{
resultText = "Unable to read Validation Table for this file.";
retCode = false;
}
}
}
catch (Exception)
{
throw;
}
return retCode;
}
Your code will look like so:
if (IsFlatFile(fileName) || IsXMLFile(fileName) || IsCSVFile(fileName))
{
btnProcess.Enabled = isCoValid(fileName);
if (!btnProcess.Enabled) break;
}
public static bool IsCSVFile(string FileName) =>
Path.GetExtension(FileName).Equals(".csv", StringComparison.OrdinalIgnoreCase);
when you write your own IsCSVFile() method and update isCoValid() method to fit your needs.
Sorry, but I can't guess what happens inside classes that are used in isCoValid() method.
Suppose that the method ReadUser below is reading the user and password in the textfile. The problem is, it doesn't read the rest of the textfile after reading the first 2 lines. How to solve this issue?
*Edit: how do I read first 2 lines then another 2 lines in the textfile ?
public override void ReadUser()
{
user = base.UserID;
password = base.Password;
using (StreamReader sr = new StreamReader(File.Open("C:\\Users\\user\\Documents\\Projects\\AdministratorModule//userTextFile.txt", FileMode.Open)))
{
user1 = sr.ReadLine();
password1 = sr.ReadLine();
sr.Close();
if (user == user1 && password == password1)
{
Console.WriteLine("Login Successfull");
}
else
{
Console.WriteLine("Login Failed");
}
}
}
simple a basic logic
int currentLine = 0;
//no need use close method with using
using (StreamReader sr = new StreamReader(File.Open("C:\\Users\\user\\Documents\\Projects\\AdministratorModule//userTextFile.txt", FileMode.Open)))
{
string line;
while ((line = sr.ReadLine()) != null)
{
switch (++currentLine)
{
case 1: user1 = line; break;
case 2: password1 = line; break;
case 3: otherVariable = line; break;
case 4: yetAnotherVariable = line; break;
......
}
//rest of your logic
}
}
However, if for some reason you need to store all the strings in an array, you're best off just using File.ReadAllLines();
I am using the stream reader feature to search for a record in a text file then display that record on the console window. It is searching the text file by a question number (1-50). The only number it works with is question 1. It won't display any other question but it displays question 1 perfect. Here is a section of the code where the problem lies.
static void Amending(QuestionStruct[] _Updating)
{
string NumberSearch;
bool CustomerNumberMatch = false;
Console.Clear();
begin:
try
{
Console.Write("\t\tPlease enter the question number you want to append: ");
NumberSearch = Console.ReadLine();
Console.ReadKey();
}
catch
{
Console.WriteLine("Failed. Please try again.");
goto begin;
}
//finding the question number to replace
while (!CustomerNumberMatch)
{
var pathToCust = #"..\..\..\Files\questions.txt";
using (StreamReader sr = new StreamReader(pathToCust, true))
{
RecCount = 0;
questions[RecCount].QuestionNum = sr.ReadLine();
if (questions[RecCount].QuestionNum == NumberSearch)
{
Console.Clear();
Console.WriteLine("Question Number: {0}", questions[RecCount].QuestionNum);
questions[RecCount].Level = sr.ReadLine();
Console.WriteLine("Level: {0}", questions[RecCount].Level);
questions[RecCount].Question = sr.ReadLine();
Console.WriteLine("Question: {0}", questions[RecCount].Question);
questions[RecCount].answer = sr.ReadLine();
Console.WriteLine("Answer: {0}", questions[RecCount].answer);
CustomerNumberMatch = true;
}
RecCount++;
//sr.Dispose();
}
}
You are reopening the questions.txt file each time around your while loop, so it will start from the beginning of the file each time and never get past the first line (unless you are looking for question 1, when it will read the question detail lines). Instead, you need to loop inside of the using statement:
var pathToCust = #"..\..\..\Files\questions.txt";
using (StreamReader sr = new StreamReader(pathToCust, true))
{
while (!CustomerNumberMatch)
{
RecCount = 0;
questions[RecCount].QuestionNum = sr.ReadLine();
if (questions[RecCount].QuestionNum == NumberSearch)
{
Console.Clear();
Console.WriteLine("Question Number: {0}", questions[RecCount].QuestionNum);
questions[RecCount].Level = sr.ReadLine();
Console.WriteLine("Level: {0}", questions[RecCount].Level);
questions[RecCount].Question = sr.ReadLine();
Console.WriteLine("Question: {0}", questions[RecCount].Question);
questions[RecCount].answer = sr.ReadLine();
Console.WriteLine("Answer: {0}", questions[RecCount].answer);
CustomerNumberMatch = true;
}
RecCount++;
}
}
Something still seems a little off with the code - e.g. you are only populating the question properties when you find a match with NumberSearch, but hopefully this gets you closer.
class Program
{
static string strFile = "Student Database.txt";
static void Main(string[] args)
{
string strInput = null; // user input string
start:
System.IO.DirectoryInfo dir = new DirectoryInfo("student_results.txt");
// Request user input as to actions to be carried out
Console.WriteLine("\nWhat do you want to do?\n" +
" 1.View Student(s)\n 2.Add a New Student\n 3.Exit program");
// Save user input to make decision on program operation
strInput = Console.ReadLine();
// Switch statement checking the saved user input to decide the action
// to be carried out
switch (strInput)
{
case "1": // choice for view file
Console.Clear();
string file = AppDomain.CurrentDomain.BaseDirectory +
#"student_results.txt";
StreamReader sr = new StreamReader(file);
string wholeFile = sr.ReadToEnd();
Console.Write(wholeFile + "");
sr.Close();
goto start;
...
}
...
}
...
}
I want this part of my code to just read the students indivially and relay them back to me, instead of how it is doing so at the moment were it just calls all of them back to me when I press '1) view Student' it pretty much says "please enter the students name or ID number of which student you would like to view".
I've currently have got the ID number running off a random number generator.
Thank you for your time guys.
Welcome to SO, first of all goto is not a good choice in C# in 99% of cases, and you'd better use loops. For your code I would save each student in a single line and at the time of reading students I would read them line by line untill I found the student.
class Program
{
static string strFile = "Student Database.txt";
static void Main(string[] args)
{
string strInput = ""; // user input string
while (strInput != "3")
{
System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo("student_results.txt");
Console.WriteLine("\nWhat do you want to do?\n 1.View Student(s)\n 2.Add a New Student\n 3.Exit program"); // request user input as to actions to be carried out
strInput = Console.ReadLine(); //save user input to make decision on program operation
switch (strInput)
{
case "1":
Console.Clear();
Console.WriteLine("Enter Student ID: \n");
string file = AppDomain.CurrentDomain.BaseDirectory + #"student_results.txt";
StreamReader sr = new StreamReader(file);
string StudentID = Console.ReadLine();
string line = "";
bool found = false;
while((line = sr.ReadLine()) != null)
{
if (line.Split(',')[0] == StudentID)
{
found = true;
Console.WriteLine(line);
break;
}
}
sr.Close();
if (!found)
{
Console.WriteLine("Not Found");
}
Console.WriteLine("Press a key to continue...");
Console.ReadLine();
break;
case "2":
Console.WriteLine("Enter Student ID : ");
string SID = Console.ReadLine();
Console.WriteLine("Enter Student Name : ");
string SName = Console.ReadLine();
Console.WriteLine("Enter Student Average : ");
string average = Console.ReadLine();
string wLine = SID + "," +SName+":"+average;
file = AppDomain.CurrentDomain.BaseDirectory + #"student_results.txt";
StreamWriter sw = File.Exists(file) ? File.AppendText(file) : new StreamWriter(file);
sw.WriteLine(wLine);
sw.Close();
Console.WriteLine("Student saved on file, press a key to continue ...");
Console.ReadLine();
Console.Clear();
break;
case "3":
return;
default:
Console.Clear();
Console.WriteLine("Invalid Command!\n");
break;
}
}
}
}
this code might not be complete, I wanted to give you the idea, I hope it helps.
Presuming you are not dealing with a huge file of students, and on the basis that you want to make multiple queries, i would not read the text file line by line each time.
Instead create a student class, read the file once on init, and create a list< student > from the data. Then you can query it with LinQ
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ReadStudents
{
class Program
{
static string _filename = "students.txt";
static void Main(string[] args)
{
List<Student> students = new List<Student>();
// Load students.
StreamReader reader = new StreamReader(_filename);
while (!reader.EndOfStream)
students.Add( new Student( reader.ReadLine()));
reader.Close();
string action;
bool showAgain = true;
do
{
Console.WriteLine("");
Console.WriteLine("1. See all students.");
Console.WriteLine("2. See student by ID.");
Console.WriteLine("3. Add new student.");
Console.WriteLine("0. Exit.");
Console.WriteLine("");
action = Console.ReadLine();
switch (action)
{
case "1":
foreach (Student item in students)
item.Show();
break;
case "2":
Console.Write("ID = ");
int id = int.Parse( Console.ReadLine() ); // TODO: is valid int?
foreach (Student item in students)
if (item.Id == id)
item.Show();
break;
case "3":
Console.WriteLine("ID-Name");
Student newStudent = new Student(Console.ReadLine());
students.Add(newStudent);
StreamWriter writer = new StreamWriter(_filename, true);
writer.WriteLine(newStudent);
writer.Close();
break;
case "0":
Console.WriteLine("Bye!");
showAgain = false;
break;
default:
Console.WriteLine("Wrong action!");
break;
}
}
while (showAgain);
}
}
class Student
{
public int Id;
public string Name;
public Student(string line)
{
string[] fields = line.Split('-');
Id = int.Parse(fields[0]);
Name = fields[1];
}
public void Show()
{
Console.WriteLine(Id + ". " + Name);
}
}
}
I assume your data are in "ID-Name" format for example:
1-Alexander
2-Brian
3-Christian
I load file line-by-line and pass to Student class which converts in constructor text data to more friendly form. Next, application shows interface until user write "0".
See the program below:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace FileOperation1
{
class FileMain
{
static void Main(string[] args)
{
FileMain fm = new FileMain();
char ch = fm.Menu();
while (ch != '0')
{
switch (ch)
{
case '0':
break;
case '1':
//Console.WriteLine("This featute is not implemented till now.");
break;
case '2':
Console.Write("Enter the name of the file: ");
String FileName = Console.ReadLine();// ReadLine() method is not workin here
FileOperation Fo=new FileOperation();
Console.WriteLine("\n" + Fo.FileRead(FileName, FileMode.Open, FileAccess.Read));
break;
case '3':
//Console.WriteLine("This featute is not implemented till now.");
break;
default:
Console.WriteLine("Invalid choice. Enter again.");
break;
}
ch = fm.Menu();
}
}
private char Menu()
{
Console.WriteLine("\n\t***File Operations***");
Console.WriteLine("1. Create a new file");
Console.WriteLine("2. Open a file");
Console.WriteLine("3. Edit an existing file");
Console.WriteLine("0. Exit");
Console.Write("\nEnter your choice: ");
char ch = Convert.ToChar(Console.Read()); //Read() Method is not working properly
return ch;
}
}
public class FileOperation
{
private String FileRead(FileStream Fs)
{
StreamReader Sr = new StreamReader(Fs);
Sr.BaseStream.Seek(0, SeekOrigin.Begin);
String str = ""+(Char)Sr.Read();
String ret = "";
while (!Sr.EndOfStream)
{
ret += str;
str = ""+(Char)Sr.Read();
}
Sr.Close();
return ret;
}
public String FileRead(String FileName, FileMode Fm, FileAccess Fa)
{
FileOperation Fo = new FileOperation();
FileStream Fs = new FileStream(FileName, Fm, Fa);
String ret = Fo.FileRead(Fs);
Fs.Close();
return ret;
}
}
}
I am using Visual Studio 2005. Here Console.ReadLine() and Console.Read() functions are not working properly for this program. Why?
You may want to try Console.ReadKey(true) , this waits for the next key press then continues, the function returns a ConsoleKeyInfo. You could use a switch statement when referring to the ConsoleKey value in the Key property:
var c = Console.ReadKey();
Console.WriteLine();
Console.WriteLine(c.Key.ToString());
// Prints
//a
//A
switch(c.Key)
{
case ConsoleKey.D0:
//User entered 0
Console.WriteLine("Exiting...");
break;
case ConsoleKey.D1:
//User entered 1
Console.WriteLine("You chose to create a new file!");
break;
case ConsoleKey.D2:
//User entered 2
Console.WriteLine("You chose to open a file!");
break;
case ConsoleKey.D3:
//User entered 3
Console.WriteLine("You chose to edit an existing file!");
break;
default:
Console.WriteLine("No response for that key");
break;
}
Console.ReadLine();
Replace Console.Read() methods with Console.ReadLine(). See more about Console.Read() and Console.ReadLine() method from MSDN. Edited program is given below:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace FileOperation1
{
class FileMain
{
static void Main(string[] args)
{
FileMain fm = new FileMain();
char ch = fm.Menu();
while (ch != '0')
{
switch (ch)
{
case '0':
break;
case '1':
//Console.WriteLine("This featute is not implemented till now.");
break;
case '2':
Console.Write("Enter the name of the file: ");
String FileName = Console.ReadLine();// ReadLine() method is not workin here
FileOperation Fo = new FileOperation();
Console.WriteLine("\n" + Fo.FileRead(FileName, FileMode.Open, FileAccess.Read));
break;
case '3':
//Console.WriteLine("This featute is not implemented till now.");
break;
default:
Console.WriteLine("Invalid choice. Enter again.");
break;
}
ch = fm.Menu();
}
}
private char Menu()
{
Console.WriteLine("\n\t***File Operations***");
Console.WriteLine("1. Create a new file");
Console.WriteLine("2. Open a file");
Console.WriteLine("3. Edit an existing file");
Console.WriteLine("0. Exit");
Console.Write("\nEnter your choice: ");
char ch = Convert.ToChar(Console.ReadLine()); //Read() Method is not working properly
return ch;
}
}
public class FileOperation
{
private String FileRead(FileStream Fs)
{
StreamReader Sr = new StreamReader(Fs);
Sr.BaseStream.Seek(0, SeekOrigin.Begin);
String str = "" + (Char)Sr.Read();
String ret = "";
while (!Sr.EndOfStream)
{
ret += str;
str = "" + (Char)Sr.Read();
}
Sr.Close();
return ret;
}
public String FileRead(String FileName, FileMode Fm, FileAccess Fa)
{
FileOperation Fo = new FileOperation();
FileStream Fs = new FileStream(FileName, Fm, Fa);
String ret = Fo.FileRead(Fs);
Fs.Close();
return ret;
}
}
}