Вы можете сделать что-то вроде этого ...
#include<iostream>
using namespace std;
//for changing values in 2D array
void myFunc(double *a,int rows,int cols){
for(int i=0;i<rows;i++){
for(int j=0;j<cols;j++){
*(a+ i*rows + j)+=10.0;
}
}
}
//for printing 2D array,similar to myFunc
void printArray(double *a,int rows,int cols){
cout<<"Printing your array...\n";
for(int i=0;i<rows;i++){
for(int j=0;j<cols;j++){
cout<<*(a+ i*rows + j)<<" ";
}
cout<<"\n";
}
}
int main(){
//declare and initialize your array
double a[2][2]={{1.5 , 2.5},{3.5 , 4.5}};
//the 1st argument is the address of the first row i.e
//the first 1D array
//the 2nd argument is the no of rows of your array
//the 3rd argument is the no of columns of your array
myFunc(a[0],2,2);
//same way as myFunc
printArray(a[0],2,2);
return 0;
}
Ваш выход будет следующим:
11.5 12.5
13.5 14.5
Начиная с API 19 (KitKat) почти невозможно напрямую записать содержимое SDcard как простое File
, потому что они смонтированы как ТОЛЬКО ЧТЕНИЕ, по крайней мере, для пользователя по умолчанию (система все еще может писать в него).
DocumentsProvider
API довольно запутанный (даже образец в документах трудно читаемый), поэтому было добавлено DocumentFile
для имитации поведения File
для более легкого доступа.
Предполагая, что пользователь уже предоставил разрешения на чтение / запись для хранения, нам нужно получить URI документа корневого каталога SDcard (в Activity
):
var sdCardUri : Uri? = null
private fun requestSDCardPermissions(){
if(Build.VERSION.SDK_INT < 24){
startActivityForResult(Intent(Intent.ACTION_OPEN_DOCUMENT_TREE), REQ_PICK_DIRECTORY)
return
}
// find removable device using getStorageVolumes
val sm = getSystemService(Context.STORAGE_SERVICE) as StorageManager
val sdCard = sm.storageVolumes.find { it.isRemovable }
if(sdCard != null){
startActivityForResult(sdCard.createAccessIntent(null), REQ_SD_CARD_ACCESS)
}
}
Перед тем, как пользователю API 24 нужно открыть средство выбора документов и вручную выберите SD-карту сами. Это не идеально, но команда Android упустила из виду тот факт, что отсутствует API SD-карт.
В более новой версии getStorageVolumes()
позволяет нам находить SD-карту через код и отображать только явное предупреждение пользователю о том, что к нему будет произведен доступ. Это НЕ тот же диалог, что и у разрешения на чтение / запись.
Теперь для обработки полученного Uri
нам нужно только взять data.data
результата. Это может быть хорошим местом для сохранения его в общих настройках, чтобы не просить пользователя снова и снова:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if(requestCode == REQ_SD_CARD_ACCESS || requestCode == REQ_PICK_DIRECTORY){
if(resultCode == RESULT_OK) {
if(data == null){
Log.e(TAG, "Error obtaining access")
}else{
sdCardUri = data.data
Log.d("StorageAccess", "obtained access to $sdCardUri")
// optionally store uri in preferences as well here { ... }
}
}else
Toast.makeText(this, "access denied", Toast.LENGTH_SHORT).show()
return
}
super.onActivityResult(requestCode, resultCode, data)
}
Я пропущу большинство проверок ошибок / проверок существующих файлов, но теперь вы можете использовать полученные sdCardUri
] вот так (копирование файла «sample.txt» из корня внутреннего хранилища в корень SDcard):
private fun copyToSDCard(){
val sdCardRoot = DocumentFile.fromTreeUri(this, sdCardUri)
val internalFile = File(Environment.getExternalStorageDirectory(), "sample.txt")
// get or create file
val sdCardFile = sdCardRoot.findFile("sample.txt") ?: sdCardRoot.createFile(null, "sample.txt")
val outStream = contentResolver.openOutputStream(sdCardFile.uri)
outStream.write(internalFile.readBytes())
outStream.flush()
outStream.close()
Toast.makeText(this, "copied to SDCard", Toast.LENGTH_SHORT).show()
}
И наоборот (из SDcard во внутреннее хранилище):
private fun copyToInternal(){
val sdCardRoot = DocumentFile.fromTreeUri(this, sdCardUri)
val internalFile = File(Environment.getExternalStorageDirectory(), "sample.txt")
val sdCardFile = sdCardRoot.findFile("sample.txt")
val inStream = contentResolver.openInputStream(sdCardFile.uri)
internalFile.writeBytes(inStream.readBytes())
inStream.close()
Toast.makeText(this, "copied to internal", Toast.LENGTH_SHORT).show()
}